Mor*_*nor 10 python bash awk yaml sed
我正在尝试编辑以下 YAML 文件
db:
host: 'x.x.x.x.x'
main:
password: 'password_main'
admin:
password: 'password_admin'
Run Code Online (Sandbox Code Playgroud)
为了编辑该host
部分,我开始使用它
sed -i "/^\([[:space:]]*host: \).*/s//\1'$DNS_ENDPOINT'/" config.yml
Run Code Online (Sandbox Code Playgroud)
但是我找不到更新main
和admin
(它们是不同的值)的密码的方法。
我试图玩弄\n
和[[:space:]]
,得到了不同的口味:
sed -i "/^\([[:space:]]*main:\n*[[:space:]]*password: \).*/s//\1'$DNS_ENDPOINT'/" config.yml
Run Code Online (Sandbox Code Playgroud)
但从来没有让它工作。非常感谢任何帮助!
编辑- 要求:没有外部二进制文件/工具。只是好 ol' bash。
由于您不想安装yq
,因此可以使用您很可能已经安装的python。
以下是基本原理:
#!/usr/bin/python
import yaml
with open("file.yml") as f:
y=yaml.safe_load(f)
y['db']['admin']['password'] = 'new_admin_pass'
print(yaml.dump(y, default_flow_style=False, sort_keys=False))
Run Code Online (Sandbox Code Playgroud)
输出:
db:
host: x.x.x.x.x
main:
password: password_main
admin:
password: new_admin_pass
Run Code Online (Sandbox Code Playgroud)
可以放入bash脚本的与单行代码类似的一段Python代码如下所示(并产生相同的输出):
python -c 'import yaml;f=open("file.yml");y=yaml.safe_load(f);y["db"]["admin"]["password"] = "new_admin_pass"; print(yaml.dump(y, default_flow_style=False, sort_keys=False))'
Run Code Online (Sandbox Code Playgroud)
注意:yq
使用像( 或)这样的 YAML 解析器yq
将是一种更可靠的解决方案。
但是,我使用以下“技术”通过grep和sed的帮助来更改“预定义”行,如下所示;
/tmp/config.yml
db:
host: 'x.x.x.x.x'
main:
password: 'password_main'
admin:
password: 'password_admin'
Run Code Online (Sandbox Code Playgroud)
grep -n 'password_admin' /tmp/config.yml | cut -d ':' -f1
Run Code Online (Sandbox Code Playgroud)
6
sed
您的新密码覆盖该行:
sed -i '6s/.*/ password: \'new_admin_pass\'/' /tmp/config.yml
Run Code Online (Sandbox Code Playgroud)
新文件现在如下所示:
grep -n 'password_admin' /tmp/config.yml | cut -d ':' -f1
Run Code Online (Sandbox Code Playgroud)
笔记
请记住,密码中的任何特殊字符( &
、\
、 )都会导致行为不当!/
sed
如果缩进发生变化,这可能会失败,因为 YAML 关心缩进。就像我上面提到的,使用 YAML 解析器将是一个更可靠的解决方案!
这绝不是可靠的,yq
但awk
如果您的 yaml 文件结构与问题中的显示方式相同,您可以使用它:
pw='new_&pass'
awk -v pw="${pw//&/\\\\&}" '/^[[:blank:]]*main:/ {
print
if (getline > 0 && $1 == "password:")
sub(/\047[^\047]*\047/, "\047" pw "\047")
} 1' file
Run Code Online (Sandbox Code Playgroud)
db:
host: 'x.x.x.x.x'
main:
password: 'new_&pass'
admin:
password: 'password_admin'
Run Code Online (Sandbox Code Playgroud)
$ awk -v new="'sumthin'" 'prev=="main:"{sub(/\047.*/,""); $0=$0 new} {prev=$1} 1' file
db:
host: 'x.x.x.x.x'
main:
password: 'sumthin'
admin:
password: 'password_admin'
Run Code Online (Sandbox Code Playgroud)
或者,如果您的新文本可以包含您不希望扩展的转义序列(例如\t
或\n
),这在设置密码时似乎很可能,那么:
new="'sumthin'" awk 'prev=="main:"{sub(/\047.*/,""); $0=$0 ENVIRON["new"]} {prev=$1} 1' file
Run Code Online (Sandbox Code Playgroud)
请参阅如何在 awk 脚本中使用 shell 变量?为什么/如何使用ENVIRON[]
访问 shell 变量而不是在第二个脚本中设置 awk 变量。
归档时间: |
|
查看次数: |
10170 次 |
最近记录: |