使用Unix命令行删除XML节点

时间:2016-11-27 11:02:57

标签: xml linux awk sed grep

我需要从文件中删除节点,如果它们没有某个标签。 我怎样才能使用awk,sed或grep?

保留具有名称标签的节点

输入:

    <node user="user1">
      <tag k="name" v="name1"/>
    </node>
    <node user="user2">
      <tag k="network" v="nw1"/>
    </node>

期望的输出:

    <node user="user1">
      <tag k="name" v="name1"/>
    </node>

3 个答案:

答案 0 :(得分:2)

如果您的文件非常简单,使用GNU awk进行多字符RS:

$ awk -v RS='</node>\n' '/v="name1"/{printf "%s%s", $0, RT}' file
    <node user="user1">
      <tag k="name" v="name1"/>
    </node>

答案 1 :(得分:1)

xmlstarlet和此文件(file.xml)的一些提示:

<root>
   <node user="user1">
      <tag k="name" v="name1"/>
    </node>
    <node user="user2">
      <tag k="network" v="nw1"/>
    </node>
   <node user="user3">
      <tag k="foo" v="bar"/>
    </node>
</root>

获取属性:

xmlstarlet sel -t -v '//root/node/tag/@v' file.xml

输出:

name1
nw1
bar

删除一个属性为v="name1"的节点:

xmlstarlet ed -d '//root/node[tag[@v="name1"]]' file.xml

输出:

<?xml version="1.0"?>
<root>
  <node user="user2">
    <tag k="network" v="nw1"/>
  </node>
  <node user="user3">
    <tag k="foo" v="bar"/>
  </node>
</root>

删除属性为v="name1"v="bar"的两个节点:

xmlstarlet ed -d '//root/node[tag[@v="name1"]]' -d '//root/node[tag[@v="bar"]]' file.xml

输出:

<?xml version="1.0"?>
<root>
  <node user="user2">
    <tag k="network" v="nw1"/>
  </node>
</root>

答案 2 :(得分:1)

使用GNU grep:

grep -Poz '.*<node .*\n.*<tag .*v="name1".*\n.*</node>' file.xml

输出:

   <node user="user1">
      <tag k="name" v="name1"/>
    </node>