用bash解析XML对

时间:2013-05-16 14:14:50

标签: bash xml-parsing

我遇到了一个有趣的问题(至少对我而言)。我们来看一个xml文件:

<a>pair1a</a>
<b>pair1b</b>
<c>randomtext</c>
<a>pair2a</a>
<b>pair2b</b>
...

<b>标记始终位于<a>标记之后。我想要得到的是<a><b>之间保存和关联在一起的内容。我应该如何在 bash 中解决此问题,以便以后我可以轻松访问和管理数据?我想到了关联数组或将所有内容放在一个数组中,并用一些分隔符将内容与b分开(尽管这可能很棘手)。我的方法非常简单,就像把一切都变成两个数组,然后让它们使用单​​个索引(顺便说一句,我已经习惯了perl regex,这就是grep正在使用的)。这可以简化吗?

a_Array=$(curl --silent -L $xml | grep -oP '(?<=<a>).*?(?=</a>)')
b_Array=$(curl --silent -L $xml | grep -oP '(?<=<b>).*?(?=</b>)')

1 个答案:

答案 0 :(得分:1)

使用shell方法无法正确解析XML。有关此主题的very nice text

说到这里,规则可能有例外。例如,如果您的输入不是任意XML而是特定格式的XML,您可以使用grep等解析它。

在您的示例中,我猜元素<a>...</a><b>...</b>每个都没有属性,每个属性在空时都不会缩写为<a/>,每个都只有一行,并且始终相互跟随。此外,我想我们可以假设您的XML中不会出现[CDATA[...]]或类似内容,反过来可能会出现类似于您的元素的内容。最后,我们假设你输入中没有空格uglinesses(像< a >那样)。

如果是这种情况,你只需要'^<a>''^<b>',是的。您还可以找到grep的选项-A-B,例如:

cat my.xml | grep -A 1 '^<a>'

这将打印以<a>开头的所有行,并且每行都在这一行之后。 -B可用于在与正则表达式匹配的行之前包含行。