使用awk或sed删除XML中含特殊字符目标串周边行并支持变量替换
正确可运行命令
首先定义你的shell变量,再执行awk命令:
namespace="NameSpace" component="customList" awk -v ns="$namespace" -v comp="$component" ' BEGIN { # 构造要匹配的完整目标字符串 match_str = "<componentName>" ns ":" comp "</componentName>" } # 第一遍读取文件,标记要删除的行号 NR == FNR { if (index($0, match_str) != 0) { # 标记当前行及上下各2行 for (i = -2; i <= 2; i++) { del[NR + i] = 1 } } next } # 第二遍读取文件,输出不在删除列表里的行 !(FNR in del) ' your_file.xml your_file.xml > result.xml
如果需要直接修改原文件,可以安装moreutils后使用sponge避免临时文件操作:
awk -v ns="$namespace" -v comp="$component" ' BEGIN { match_str = "<componentName>" ns ":" comp "</componentName>" } NR == FNR { if (index($0, match_str) != 0) { for (i = -2; i <= 2; i++) del[NR+i] = 1 } next } !(FNR in del) ' your_file.xml your_file.xml | sponge your_file.xml
原有命令失效的原因
- 最核心的问题是用双引号包裹awk代码,shell会提前解析awk内部的
$0、$NR等变量,把这些awk变量当成空的shell变量替换,导致判断逻辑完全错误,出现误删开头行的问题。 - 用正则匹配(
~运算符)处理固定字符串,需要额外处理<、/等字符的转义逻辑,很容易因为转义遗漏导致匹配失败。改用index()函数做纯文本子串匹配,不需要处理任何转义,稳定性更高。 - 之前的参数传递逻辑和双引号代码混用,变量解析顺序混乱,导致目标字符串匹配失败。
内容的提问来源于stack exchange,提问作者Patlatus
相关产品推荐
相关产品推荐

