You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用sed命令修改YAML文件含下划线键值失败求助

问题:sed修改YAML中app2的value_3值无效的原因及解决办法

原始YAML内容(test.yaml)

app1:
    value1: 0
    value2: 7
    value_3: 5
  app2:
    value1: 1
    value2: 6
    value_3: 0

现象

  • 执行以下命令可成功将app2的value2值改为0:
    sed -i '/app2/ {n;N;s/value2: 6/value2: 0/}' test.yaml
    
  • 但执行类似命令修改app2的value_3值时,无报错但值未变化:
    sed -i '/app2/ {n;N;s/value_3: 0/value_3: 6/}' test.yaml
    

原因

这不是sed的bug,是操作逻辑有误。/app2/ {n;N;...}的执行流程是:

  1. 匹配到app2:所在行后,n命令读取下一行(即 value1: 1)并替换当前模式空间内容;
  2. 接着N命令再读取下一行(即 value2: 6)追加到模式空间,此时模式空间里只有这两行内容;
  3. 后续的s命令只能在这两行里匹配替换,而value_3: 0是app2下的第三行,根本没被读到模式空间中,所以替换无效。

解决办法

方法1:使用地址范围匹配

通过指定从app2:到下一个app节点的范围,在这个范围内替换目标值:

sed -i '/app2:/,/^  [a-z0-9]*:/ s/value_3: 0/value_3: 6/' test.yaml
  • /app2:/:匹配app2节点的起始行
  • /^ [a-z0-9]*:/:匹配下一个以两个空格开头的app节点行(适配YAML的缩进格式)
  • 中间的s命令会在这个范围内所有行中执行替换

方法2:循环读取直到找到目标行

用sed的标签循环,读取app2之后的行直到找到value_3:并替换,可选添加退出条件避免影响后续内容:

# 无退出条件(适用于app2是最后一个节点的情况)
sed -i '/app2:/ { :loop; n; /value_3:/ s/0/6/; b loop }' test.yaml

# 带退出条件(读到下一个app节点就停止,更安全)
sed -i '/app2:/ { :loop; n; /^  [a-z0-9]*:/q; /value_3:/ s/0/6/; b loop }' test.yaml
  • :loop:定义循环标签
  • n:读取下一行
  • /^ [a-z0-9]*:/q:匹配到下一个app节点时退出(q命令结束sed进程)
  • /value_3:/ s/0/6/:匹配到目标行时执行替换
  • b loop:跳回loop标签继续循环

内容的提问来源于stack exchange,提问作者theghoul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:42:37