如何使用sed在匹配行下方保留前置缩进批量新增配置行
解决方案
你之前的命令问题在于硬编码了新增行的缩进,我们可以通过动态捕获匹配行的前置缩进实现适配,以下是两种稳定可用的方案:
方案1:awk 实现(推荐,可读性高,跨平台兼容性好)
GNU Awk 4.1及以上版本支持原地修改文件,逻辑直观不易出错:
awk -i inplace ' # 跳过纯注释行直接输出 /^[[:space:]]*#/ { print; next } # 匹配目标行 /caseSensitive: false/ { # 先输出原行 print # 提取行首的空白字符作为缩进 match($0, /^[[:space:]]*/) indent = substr($0, RSTART, RLENGTH) # 输出带相同缩进的新行 print indent "printMatchedString: false" next } # 其他行直接输出 1' /path/to/your/config/dir/*
如果需要批量处理子目录下所有匹配的配置文件,配合find使用:
find /path/to/root/dir -name "*.yaml" -type f -exec awk -i inplace ' /^[[:space:]]*#/ { print; next } /caseSensitive: false/ { print match($0, /^[[:space:]]*/) indent = substr($0, RSTART, RLENGTH) print indent "printMatchedString: false" next } 1' {} \;
如果是macOS系统,可先通过brew install gawk安装GNU Awk,把命令中的awk替换为gawk即可使用。
方案2:GNU Sed 实现
Linux系统默认带的GNU Sed也可以实现,适合习惯用sed的场景:
sed -i -E '/^[[:space:]]*#/b; /caseSensitive: false/{p;s/^([[:space:]]*).*/\1printMatchedString: false/}' /path/to/your/config/dir/*
命令逻辑说明:
- 匹配到注释行直接跳过处理
- 匹配到目标行时,先输出原行(
p命令),再把行内容替换为「捕获的缩进+新行内容」输出
如果是macOS使用BSD Sed,把-i改为-i ''即可。
内容的提问来源于stack exchange,提问作者Sureshchandra Jarugula
相关产品推荐
相关产品推荐

