我的处境与本文中的人非常相似。我正试图编写一个脚本来填充database.yaml文件中的值。问题是……我完全不明白作为解决方案发布的正则表达式中发生了什么。
我想做的是为密码传递变量。
如果我有一个数据库yml文件,看起来像这样:
development:
database: sample_development
password:
# etc...
test:
database: sample_test
password:
# etc...
那么如何创建一个查找"password:"的正则表达式,以便我可以将其替换为"password:$new_password"?
对于脚本中设置开发密码的部分,我猜regex将以开头
/^development:
但我不知道该如何抓住下一行"密码:"。
你知道我该怎么做吗?
我只需要使用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脚本,该脚本将接受params来设置密码、主机名等。除此之外,您只需在YAML文件中使用ruby即可使其动态,YAML本身可以读取配置文件或环境变量,并使用它们设置密码、主机名等。
host: <%= SERVER_CONFIG["dev_host"] %>
您可以使用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个标签。
restart
用于返回到脚本的开头- CCD_ 3用于在CCD_
stop
是在我们对密码进行更改时使用的,并且我们转到脚本的末尾,这实际上允许脚本在下一个输入行重新启动
在主块中,我们首先尝试使用s
替代命令应用密码更改。如果有效,后面的t
测试命令会跳到脚本的末尾,以便在找到另一个development
块的情况下继续执行。
如果替换命令不成功,t
命令将不执行任何操作,我们将继续执行n
下一个命令。该命令将下一个输入行加载到模式空间(即sed的工作缓冲区)。然后,我们检查它是否以空格或制表符开头,如果是,我们跳到"循环"标签,让我们看到这一新行是否是包含密码字段的行。
如果它不是以空白字符开头,那么我们已经到达了块的末尾。i
插入命令是可选的,但使用它,当找不到密码行时,我们可以在块的末尾添加密码行。
最后,由于我们到达了块的末尾,我们必须重新开始执行。我们可以让执行读取脚本的末尾,但由于我们加载了一行不是以空格字符开头的新行,我们必须手动跳到开头,以防止sed在重新启动之前加载另一行。
然后,您可以使用:运行这个脚本(假设它被称为chg_passwd.sed
)
./chg_passwd.sed database.yml
希望这有帮助=)
这可能对您有用:
database=foo newpassword=bar
sed '/^'"${database}"'/,/^s*$/s/password:/&'"${newpassword}"'/' file