如何用sed在文件中替换内容但跳过匹配多模式的行?
解决sed中跳过多个XML元素进行替换的问题
我来帮你搞定这个sed多元素跳过的问题!你遇到的核心问题是sed默认使用基础正则表达式(BRE),而你尝试的几种写法要么没有正确转义特殊字符,要么混淆了正则模式的语法规则。
为什么之前的写法失败?
在sed的默认BRE模式下:
- 竖线
|是普通字符,不是“或”操作符,必须转义成\|才能表示逻辑或 - 分组括号
()也需要转义成\(和\),才能用来分组多个匹配模式 - 你第一种写法
/(OtherElement|ApplicationUser)/!s/.../g里的|会被当作字面字符,所以实际匹配的是包含OtherElement|ApplicationUser这个完整字符串的行,而不是包含两个元素之一的行,自然达不到跳过的效果。
正确的解决方案
根据你是从文件加载sed命令的场景,分两种情况处理:
1. 使用基础正则表达式(BRE)的脚本写法
创建一个sed脚本文件(比如replace_script.sed),内容如下:
/\(OtherElement\|ApplicationUser\)/!s/"user.name"/"user.name@abc.com"/g
然后运行命令:
sed -f replace_script.sed your_target.xml
这个写法里:
\(OtherElement\|ApplicationUser\):正确转义了分组和或操作符,匹配包含OtherElement或ApplicationUser的行!s/.../.../g:对不匹配上述模式的行执行替换操作
2. 使用扩展正则表达式(ERE)的脚本写法
如果你觉得BRE的转义太麻烦,可以用sed的-E选项启用扩展正则表达式,这样就不需要转义括号和竖线了。脚本文件内容可以简化为:
/(OtherElement|ApplicationUser)/!s/"user.name"/"user.name@abc.com"/g
运行命令时加上-E参数:
sed -E -f replace_script.sed your_target.xml
额外注意事项
- 如果你的XML元素是带尖括号的标签(比如
<ApplicationUser>),为了避免误匹配到内容中的相同字符串,建议把正则改成匹配标签本身:
BRE写法:/\(<OtherElement>\|<ApplicationUser>\)/!s/.../g
ERE写法:/(<OtherElement>|<ApplicationUser>)/!s/.../g - sed是逐行处理文本的,如果你的XML元素标签跨多行(比如标签和内容不在同一行),这种方法可能失效。如果是复杂的XML处理场景,更推荐用专门的XML工具(比如
xmlstarlet)来操作,避免正则处理XML的局限性。
内容的提问来源于stack exchange,提问作者Colin Goudie
相关产品推荐
相关产品推荐

