使用sed清除XML <logos>节点内容失败,如何修正?
问题原因及解决方案
你的sed命令失效主要有两个核心问题:
1. 正则表达式语法不兼容sed默认模式
sed默认使用基本正则表达式(BRE),而你用的+是扩展正则表达式(ERE)里的元字符(表示匹配一个或多个前导字符)。在BRE中,+会被当成普通字符处理,所以你的\(.+\)根本匹配不到<logos>和</logos>之间的内容。
2. 不必要的忽略大小写选项
你加了i选项(忽略大小写),但XML标签是大小写敏感的,<logos>和<Logos>是完全不同的节点,这个选项不仅没用,还可能导致意外匹配(虽然这里不会,但属于冗余)。
针对单行内容的修复方案
如果你的<logos>节点和内容都在同一行,有两种修复方式:
方式一:启用扩展正则(推荐)
给sed加-E选项,这样就能直接使用+这类ERE元字符:
sed -i -E 's|<logos>.+</logos>|<logos></logos>|g' "$filename"
方式二:转义BRE中的+
如果你不想用扩展正则,把+转义成\+即可:
sed -i 's|<logos>.\+</logos>|<logos></logos>|g' "$filename"
针对跨行内容的修复方案
如果<logos>节点的内容是跨多行的(比如每个<logo>标签单独占一行),上面的单行匹配就会失效。这时可以用GNU sed的-z选项,它会把整个文件当成一个连续的字符串(忽略换行符),让.*可以跨行匹配:
sed -i -z 's|<logos>.*</logos>|<logos></logos>|g' "$filename"
注:-z是GNU sed的特性,如果你用的是BSD sed(比如macOS默认的sed),需要换用其他方式,比如用awk或者Perl来处理跨行匹配。
内容的提问来源于stack exchange,提问作者Dr. Gianluigi Zane Zanettini
相关产品推荐
相关产品推荐

