我有一个非常大的XML文件,我需要从中提取一些信息。我一直试图用sed
脚本来做这件事,但我遇到了一些问题。实际上有两个版本的同一个XML文件,一个格式很好,一个只是一个巨大的单行XML。我对每个人都有不同的问题。
我想从中提取数据的一个元素叫做<name>
,但是这个元素有多个实例,我只想要数据在一个特定的上下文中。这就是我的意思:
XML看起来像这样:
<object uid="1234567890-00000000">
<name>Object Name</name>
<country>United States</country>
<state>Texas</state>
<county>Travis</county>
<timeZone>-06:00</timeZone>
<datum uid="datum_UID">
<name>Datum Name</name>
<code>DUID</code>
</datum>
</object>
我的最终目标是生成一个两列,空白分隔的文件,其中包含第一列中的对象uid
和第二列中的对象name
。我的第一个想法是每个单独的sed
,并使用结果构建两个临时文件,然后将它们合并为一个。问题是,当sed
为name元素时,我无法弄清楚如何只获取对象<name>
元素,而不是基准<name>
元素。
用于查找对象sed
的{{1}}脚本似乎完美无缺:
uid
sed -n -e 's/^.*<object uid="\([-0-9]*\)">.*/\1/p' $infile > $outfile
是大型XML文件,而$infile
是我想要保存生成的$outfile
的地方。以下是uid
的内容,显然无效,因为它与name
代码的每个实例都匹配:
<name>
有没有办法用sed -n -e 's/^.*<name>\([^<]*\)<.*/\1/p' $infile > $outfile2
执行此操作?请记住,文件非常大(超过5000万行)。我发现this blog有一个我可以尝试的多行搜索,但是如果我正确理解它,这会在搜索之前将所有行连接到保持缓冲区,而我对{{ {1}}要知道50mil +行是否真的非常糟糕。
我尝试使用一个sed
脚本使用单行文件一步完成所有操作,但我最终只获得了最后一个匹配作为输出。这是我用过的sed
脚本:
sed
我想我知道为什么这个表达式不起作用(开头的sed
和结尾匹配我想要的数据之前/之后的所有内容),但我无法修复它。我在表达式中尝试了一些变化,但我从来没有得到我正在寻找的结果。要么它只打印最后一个结果,要么打印整行(在这种情况下是整个文件)。如何解析单行文件中的每个匹配?
答案 0 :(得分:1)
以下是使用XML解析工具xmlstarlet
:
xmlstarlet sel -t -m //object -v @uid -nl -v name -nl test.xml | paste - -
1234567890-00000000 Object Name
2 second
给出这个“test.xml”:
<objects>
<object uid="1234567890-00000000">
<name>Object Name</name>
<country>United States</country>
<state>Texas</state>
<county>Travis</county>
<timeZone>-06:00</timeZone>
<datum uid="datum_UID">
<name>Datum Name</name>
<code>DUID</code>
</datum>
</object>
<object uid="2">
<name>second</name>
<datum uid="datum_UID">
<name>not me</name>
</datum>
</object>
</objects>