用于提取递归xml标记的Shell脚本

时间:2013-10-09 17:29:39

标签: xml bash shell sed

我有一个格式为的XML文件:

...
<element1>
<element2>
<group1>
<tag1>value</tag1>
<tag2>value</tag2>
</group1>
<group1>
<tag1>value</tag1>
<tag2>value</tag2>
</group1>
<element2>
...

我用过

sed -n '/\<group1\>/,\<\/group1>/p' filename

提取group1标签的所有内容,包括所有子标签。这正是我想要的。

<group1>
<tag1>value</tag1>
<tag2>value</tag2>
</group1>
<group1>
<tag1>value</tag1>
<tag2>value</tag2>
</group1>

但是,如果输入XML的格式为

...
<element1>
<element2>
<group2>
     <group2>value</group2>
     <otherTag>value</otherTag>
</group2>
<element3>
<group2>
     <group2>value</group2>
     <otherTag>value</otherTag>
</group2>
...

我尝试提取以下内容

<group2>
     <group2>value</group2>
     <otherTag>value</otherTag>
</group2>
<group2>
     <group2>value</group2>
     <otherTag>value</otherTag>
</group2>

上面的sed命令只返回:

<group2>
     <group2>value</group2>

它理解停止模式</group2>并且不再提取。我在这里很困惑。为什么不继续提取下一个<group2>,如同<group1>一样。有没有办法让它与sed一起使用?和其他任何替代方案?

3 个答案:

答案 0 :(得分:1)

您可以像这样更改sed

sed -n '/\<group1\>/,/^<\/group1>/p' filename  | grep -v 'element3'

答案 1 :(得分:1)

最好将XPath与命令行xpath解释器一起使用,如xpath,xmlstarlet,my xidel或xmllint。

第3级的所有组元素:

/elememt1/*/group1

所有不包含group2的组元素:

//group2[not(group2)]

答案 2 :(得分:0)

有人这样吗?

awk '/^<group2>/,/^<\/group2>/' file
<group2>
     <group2>value</group2>
     <otherTag>value</otherTag>
</group2>
<group2>
     <group2>value</group2>
     <otherTag>value</otherTag>
</group2>

如果标签上有不同的间距,如果全部调整到左侧,则无效