如何用Shell脚本批量删除YML文件指定节点下的匹配内容
问题描述
我的abcd.yml文件内容如下:
buildConfig: env: credentials: # 要删除这部分内容 - id: TEST_ID # 要删除这部分内容 user: username # 要删除这部分内容 password: password # 要删除这部分内容 scan: credentials: - id: scan_id user: username password: password
我尝试用以下sed命令删除目标行:
sed -i '/credentials:/d' abcd.yml sed -i '/- id: TEST_ID/d' abcd.yml sed -i '/user: username/d' abcd.yml sed -i '/password: password/d' abcd.yml
但这些命令会删除文件中所有匹配的字符串,并非我想要的效果。我需要只删除buildConfig -> env下的credentials及其子项,保留scan下的对应内容,期望输出:
buildConfig: env: scan: credentials: - id: scan_id user: username password: password
同时需要对1000个YML文件执行此操作,求可行的脚本方案。
解决方案:用awk精准匹配层级
YAML依赖缩进区分层级,我们可以通过上下文和缩进规则精准定位要删除的块。下面的方案能避免误删其他区块的内容:
单文件处理命令
awk ' /^buildConfig:/ { in_build=1 } /^scan:/ { in_build=0 } in_build && /^ env:/ { in_env=1; print; next } in_env && /^ credentials:/ { skip=1; next } skip && /^ / { next } skip && !/^ / { skip=0; next } { print } ' abcd.yml > temp.yml && mv temp.yml abcd.yml
逻辑说明
- 匹配
buildConfig:时,标记进入buildConfig区块 - 匹配
scan:时,退出buildConfig区块 - 在buildConfig区块内匹配到
env:时,标记进入env区块并打印该行 - 在env区块内匹配到
credentials:时,开始跳过后续行 - 处于跳过状态且行缩进为8个空格时(credentials的子项),继续跳过
- 缩进不再符合子项规则时,退出跳过状态
- 其他所有情况正常打印行
批量处理脚本
如果要处理当前目录下所有.yml文件,可创建如下bash脚本:
#!/bin/bash for file in *.yml; do echo "正在处理 $file..." awk ' /^buildConfig:/ { in_build=1 } /^scan:/ { in_build=0 } in_build && /^ env:/ { in_env=1; print; next } in_env && /^ credentials:/ { skip=1; next } skip && /^ / { next } skip && !/^ / { skip=0; next } { print } ' "$file" > temp.yml && mv temp.yml "$file" done
将脚本保存为clean_yml.sh,执行以下命令启用并运行:
chmod +x clean_yml.sh ./clean_yml.sh
注意事项
- 确保YAML文件使用空格而非制表符缩进,脚本中的匹配规则基于原文件的4空格缩进层级,若你的文件缩进规则不同(比如2空格),需调整脚本中
^ env:、^ credentials:等匹配项的空格数量 - 脚本会直接修改原文件,建议先挑选1-2个文件测试效果,再批量执行
内容的提问来源于stack exchange,提问作者abhi c
相关产品推荐
相关产品推荐

