如何用sed/awk匹配指定应用并替换其YAML配置的value值?
仅修改YAML文件中指定应用的配置项值
问题场景
现有如下YAML格式的配置文件test.yaml,包含多个应用的配置块:
- name: my-app <<: *foo installed: true labels: code: x.x mode: y.y set: - name: a.b.c value: abc-ab1cd2 - name: d.e.f value: ab1cd2 - name: other-app set: - name: d.e.f value: should-not-change
需要仅修改my-app块下- name: a.b.c和- name: d.e.f对应的value值,而不影响其他应用的相同配置项。之前使用的sed命令会修改所有匹配到的配置项,无法限定到指定应用。
解决方案
方法1:使用sed命令
通过范围匹配锁定my-app的配置块,仅在该块内修改目标值:
sed -i '/- name: my-app/,/^- name:/ { /- name: a.b.c/{n;s/value: .*/value: new-abc-value/} /- name: d.e.f/{n;s/value: .*/value: new-def-value/} }' test.yaml
- 逻辑说明:
/- name: my-app/,/^- name:/定义了操作范围——从my-app的起始行,到下一个顶层应用的- name:行结束; - 块内操作:找到目标
name行后,n跳转到下一行(即value行),替换该行的value内容。
方法2:使用awk命令(更稳定的YAML处理)
awk通过状态标记来精准控制修改范围,适合处理缩进复杂的YAML文件:
awk ' /- name: my-app/ { in_myapp = 1 } /^- name:/ && in_myapp { in_myapp = 0 } in_myapp && /- name: a.b.c/ { getline; sub(/value: .*/, "value: new-abc-value"); print; next } in_myapp && /- name: d.e.f/ { getline; sub(/value: .*/, "value: new-def-value"); print; next } 1' test.yaml > temp.yaml && mv temp.yaml test.yaml
- 逻辑说明:
- 遇到
my-app的起始行时,标记in_myapp=1(进入目标块); - 遇到下一个顶层应用的
- name:行时,取消标记(退出目标块); - 在目标块内,找到目标
name行后,getline读取下一行,替换value内容并打印,next跳过默认打印; - 最后
1表示打印所有未被特殊处理的行。
- 遇到
内容的提问来源于stack exchange,提问作者Vicky
相关产品推荐
相关产品推荐

