3

我的情况与这篇文章中的人非常相似。我正在尝试编写一个在 database.yaml 文件中填充值的脚本。问题是......我完全不明白作为解决方案发布的那个正则表达式中发生了什么。

我想要做的是传递密码变量。

如果我有一个如下所示的数据库 yml 文件:

development:
  database: sample_development
  password:
  # etc...

test:
  database: sample_test
  password:
  # etc...

那么如何创建一个找到“密码:”的正则表达式,以便我可以用“密码:$new_password”替换它?

对于设置开发密码的脚本部分,我猜正则表达式会开始

/^development:

但是我不知道如何抓住下一行'密码:'。

知道我该怎么做吗?

4

3 回答 3

3

我只会使用 YAML 库来读取/写入 yaml 文件:

require 'yaml'
database_config = YAML.load(File.open("<some path>/config/database.yml"))

然后修改一些值,写回fs:

database_config['some_key'] = "some_value"
File.open("<some path>/config/database.yml", "w") {|f| f.write(database_config.to_yaml) }

您可以创建一个 ruby​​ 脚本,该脚本将接受参数来设置密码、主机名等。除此之外,您可以在 YAML 文件中使用 ruby​​ 使其动态化,yaml 本身可以读取配置文件或环境变量并使用它们设置密码、主机名等。

host: <%= SERVER_CONFIG["dev_host"] %>
于 2012-10-07T21:09:53.823 回答
2

您可以使用 sed 脚本:

#!/bin/sed -f

: restart
/^development/ {
    : loop
    s/\(password:\).*/\1 new_password/
    t stop
    n
    /^[ \t]/ b loop
    i\  password: new_password
    b restart
} 
: stop

这里我们有一个 sed 脚本,当它找到以“development”开头的行时,它将启动主要的命令块。在解释命令的作用之前,我认为解释标签是个好主意。标签是用:命令定义的,它们为脚本中的某些位置命名。我们定义了 3 个标签。

  1. restart用于回到脚本的开头。
  2. loop用于遍历development块内的行。
  3. stop当我们对密码执行更改时使用它,然后我们转到脚本的末尾,这实际上允许脚本在下一个输入行重新启动。

在主块中,我们首先尝试使用s替代命令应用密码更改。如果它有效,则随后的测试命令将跳转到脚本的末尾,以便在找到另一个块t的情况下继续执行。development

如果替代命令不成功,则该t命令不执行任何操作,我们继续执行n下一个命令。此命令将下一个输入行加载到模式空间(即 sed 的工作缓冲区)中。然后我们检查它是否以空格或制表符开头,如果是,我们跳转到“循环”标签,让我们看看这个新行是否是包含密码字段的行。

如果它不是以空格字符开头,我们已经到达了块的末尾。插入命令是可选的i,但是我们可以在未找到时在块末尾添加密码行。

最后,由于我们到达了块的末尾,我们必须重新开始执行。我们可以让执行读取脚本的结尾,但是由于我们已经加载了一个不以空格字符开头的新行,因此我们必须手动跳转到开头以防止 sed 在重新启动之前加载另一行。

然后,您可以使用以下命令运行此脚本(假设它被称为chg_passwd.sed):

./chg_passwd.sed database.yml

希望这会有所帮助=)

于 2012-10-07T21:01:22.647 回答
1

这可能对您有用:

database=foo newpassword=bar
sed '/^'"${database}"'/,/^\s*$/s/password:/&'"${newpassword}"'/' file
于 2012-10-07T23:55:05.417 回答