我有一个包含以下内容的 xml 文件。
<contracts>
<clients>
<client>
<name>Nicol</name>
<clientRef>123</clientRef>
</client>
<client>
<name>Basil</name>
<clientRef>8234</clientRef>
</client>
</clients>
<entries>
<entry>
<regCode>BCG</regCode>
<clientRef>63352</clientRef>
</entry>
<entry>
<regCode>TYD</regCode>
<clientRef>3242</clientRef>
</entry>
</entries>
</contracts>
xml 标签“clientRef”位于客户端和条目部分。但是,我只需要删除客户端部分中的 clientRef 标签。
所需的输出是:
<contracts>
<clients>
<client>
<name>Nicol</name>
</client>
<client>
<name>Basil</name>
</client>
</clients>
<entries>
<entry>
<regCode>BCG</regCode>
<clientRef>63352</clientRef>
</entry>
<entry>
<regCode>TYD</regCode>
<clientRef>3242</clientRef>
</entry>
</entries>
</contracts>
我是 shell 和 sed 命令的新手。如何使用 shell 脚本删除 clientRef 标签?
答案1
虽然有可能,但它是一个非常非常糟糕的主意尝试使用sed
基于正则表达式的工具来解析 XML 或 HTML。这可以适用于简单的情况,但很难做到正确,即使对于专家来说,对于稍微复杂的情况。因此,请使用 XML 解析器,例如xmlstarlet
(应该可以从操作系统的存储库安装):
$ xmlstarlet ed -d '//client/clientRef' file.xml
<?xml version="1.0"?>
<contracts>
<clients>
<client>
<name>Nicol</name>
</client>
<client>
<name>Basil</name>
</client>
</clients>
<entries>
<entry>
<regCode>BCG</regCode>
<clientRef>63352</clientRef>
</entry>
<entry>
<regCode>TYD</regCode>
<clientRef>3242</clientRef>
</entry>
</entries>
</contracts>
意思ed
是“编辑此文件”,-d '//client/clientRef'
意思是“删除”clientRef
下的条目client
。
在这种特殊情况下,您还可以使用简单的文本解析工具,因此我将提供一个示例,但请不要对任何更复杂的事情执行此操作,并且请注意,即使是很小的更改,它也可能会中断。输入数据:
$ awk '{
if(/<clients>/){a=1}
else if(/<\/clients>/){a=0}
if(/<clientRef>/ && a){ next}
}1;' file.xml
<contracts>
<clients>
<client>
<name>Nicol</name>
</client>
<client>
<name>Basil</name>
</client>
</clients>
<entries>
<entry>
<regCode>BCG</regCode>
<clientRef>63352</clientRef>
</entry>
<entry>
<regCode>TYD</regCode>
<clientRef>3242</clientRef>
</entry>
</entries>
</contracts>
答案2
使用xq
XML 解析器(部分yq
),它是一个包装器jq
(因此它正在执行 XML/JSON 转码):
$ xq -x 'del(.contracts.clients.client[].clientRef)' file.xml
<contracts>
<clients>
<client>
<name>Nicol</name>
</client>
<client>
<name>Basil</name>
</client>
</clients>
<entries>
<entry>
<regCode>BCG</regCode>
<clientRef>63352</clientRef>
</entry>
<entry>
<regCode>TYD</regCode>
<clientRef>3242</clientRef>
</entry>
</entries>
</contracts>