0

我有几个非常大(10GB)的 xml 文件,具有以下结构。如您所见,该文件包含一系列记录。我想做的是基于一个或多个属性的搜索记录。问题是一个简单的 grep 会给我包含该属性的行。例如,grep 可能会给我第 100 行、第 300 行等等。但是,我需要的是提取相关记录元素的能力,而不仅仅是符合匹配项的行。是否有任何可以提供帮助的 unix 实用程序?

<records>
 <record seq="1">
  <properties>
   <property name="AssetId">1234</property>
  </properties>
 <message>messsage1</message>
</record>
<record seq="2">
 <properties>
  <property name="VI-ID">4567</property>
 </properties>
 <message>message2</message>
</record>
<records>
4

3 回答 3

4

xmlstarlet允许您从 shell 脚本运行 XPath;这是一个完美的用例。

例如:

xmlstarlet sel -t \
  -m '//record[properties/property[@name="AssetId"][text()="1234"]]' \
  -c .

将打印 AssetId 属性为 1234 的整个记录​​。

如果您想在一次通过中进行多个匹配,这也受支持:

xmlstarlet sel \
  -t -m '//record[properties/property[@name="AssetId"][text()="1234"]]' \
     -c . -n -n \
  -t -m '//record[properties/property/@name="VI-ID"]' \
     -c . -n -n \
  <input.xml

...此版本将打印 AssetID 为 1234 的记录,或任何VI-ID具有任何值的礼物的记录,并在每个记录发出后放置两个换行符。

于 2012-05-03T22:13:12.710 回答
0

可能最简单的方法是使用-C选项 to grep。它将在每个匹配项周围打印指定数量的行。是的,它不会完全停在记录边界上,但通常只要确保包含它就足以满足我的需求。

于 2012-05-03T22:06:32.560 回答
0

如果您只想使用基本的 unix 工具,这里有一个(愚蠢的)小 sed 脚本,它可以提取出一个属性,该属性要么位于一行,要么跨越多行:

sed -n '
/<open>[^<]*<\/open>/ {
  p
  b
}

/<open>/,/<\/open>/ {
  p
}' file.xml

样本输入:

<open>stuff</open>
<otherTag>
otherstuff
</otherTag>
<open>
morestuff
</open>
<otherTag>astlkj</otherTag>

样本输出:

<open>stuff</open>
<open>
morestuff
</open>

不适用于生产用途:如果一个标签有多个属性,这种方法很快就会变得困难、繁琐,而且如果 xml 足够复杂,就不可能了。但它应该可以在这里和那里解析信息。

于 2012-05-03T22:21:07.740 回答