如何通过命令行移除重复出现的XML标签块
问题描述
我有如下XML文件:
<xml> <trkseg> <note> <to>A</to> <from>B</from> <body> keep this </body> </trkseg> <trkseg> </note> ... </trkseg> </xml>
需要移除所有连续出现的</trkseg>和<trkseg>标签组合(即这两行同时出现的情况),预期得到的结果是:
<xml> <trkseg> <note> <to>A</to> <from>B</from> <body> keep this </body> </note> ... </trkseg> </xml>
我尝试用下面的sed命令处理,但结果不对:
sed -i '' -e '/<\/trkseg>/,/<trkseg>/d' my-file.xml
得到的错误结果是末尾的</trkseg>被删掉了,输出变成:
<xml> <trkseg> <note> <to>A</to> <from>B</from> <body> keep this </body> </note> ...
解决办法
原来的sed命令会删除从第一个</trkseg>行到第一个<trkseg>行的所有内容,包括这两行本身,所以才会把最后那个需要保留的</trkseg>也删掉了。
可以用下面的sed命令实现正确的替换:
sed -i '' -e '/<\/trkseg>$/{N;/\n<trkseg>$/d;}' my-file.xml
命令说明:
/<\/trkseg>$/:精准匹配以</trkseg>结尾的行{N;}:把下一行内容读入当前的模式空间,此时模式空间里是两行:</trkseg>和它后面紧跟的<trkseg>/\n<trkseg>$/d;:如果模式空间里的第二行是以<trkseg>结尾的,就删除这两行
如果你的XML标签前后有缩进空格,需要调整匹配规则来兼容空格:
sed -i '' -e '/<\/trkseg>\s*$/{N;/\n\s*<trkseg>\s*$/d;}' my-file.xml
这里的\s*用来匹配任意数量的空格或制表符,确保缩进不同的情况也能匹配到。
额外提醒
用sed这类文本工具处理XML其实并不够严谨,因为XML的结构可能有各种变化(比如标签跨多行、嵌套层级复杂)。如果是复杂的XML处理场景,建议用专门的XML工具,比如xmllint或者Python的xml.etree模块,能更可靠地处理结构问题。
内容的提问来源于stack exchange,提问作者johansson
相关产品推荐
相关产品推荐

