如何使用sed将YAML文件指定字段替换为多行字符串并保留缩进
问题原因
你遇到的sed报错主要有两个诱因:
- 你定义的
replacewith变量包含未转义的换行符,sed默认将换行识别为命令终止符,因此会判定s替换命令没有闭合的分隔符,抛出unterminated 's' command错误 - 你使用了扩展正则的
()捕获分组语法,但没有加-E(GNU sed也支持-r)参数开启扩展正则,正则逻辑无法正常解析
另外原生写法没有适配YAML的缩进要求,即使跑通也会生成格式非法的YAML文件。
解决方案
针对你的需求,我们可以提前转义替换内容的换行符,同时适配YAML缩进规则,完整实现步骤如下:
步骤1:定义变量
# 目标YAML键名 target_key="alm-examples" # 待插入的多行原始值,不需要提前加缩进 multi_value="multi line string"
步骤2:转义替换内容
将多行值的换行转义为sed可识别的\n,同时提前补好值层级相对键层级的缩进:
escaped_value=$(printf '%s' "$multi_value" | sed -e '1!s/^/\\n /' -e 's/$/ /')
步骤3:执行sed替换
使用#作为替换分隔符避免和内容冲突,同时捕获目标键的原有缩进:
# GNU sed 适用(Linux环境) sed -i -E "s#^(\s*)${target_key}\s*:.*#\1${target_key}: |-\n \1${escaped_value}#" somefile.yaml # macOS 自带sed 适用 sed -i '' -E "s#^(\s*)${target_key}\s*:.*#\1${target_key}: |-\n \1${escaped_value}#" somefile.yaml
注意事项
- 如果待插入的内容包含
#、\、&这类sed特殊字符,需要提前转义,避免解析异常 - 该方案默认遵循YAML规范,值层级比键层级多2个空格缩进,如果你实际场景的缩进是4个空格,可以调整命令里的缩进量
- 对于复杂的YAML编辑场景,更推荐使用
yq(YAML专用处理工具)实现,逻辑更简洁也不会出现格式兼容问题
内容的提问来源于stack exchange,提问作者viveksinghggits
相关产品推荐
相关产品推荐

