【发布时间】:2014-01-28 12:45:24
【问题描述】:
我有一个非常大的 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> 元素。
我用于查找对象uid 的sed 脚本似乎运行良好:
sed -n -e 's/^.*<object uid="\([-0-9]*\)">.*/\1/p' $infile > $outfile
$infile 是大 XML 文件,$outfile 是我想要保存生成的uids 的任何位置。这是我为name 提供的内容,这显然行不通,因为它将与<name> 标记的每个实例匹配:
sed -n -e 's/^.*<name>\([^<]*\)<.*/\1/p' $infile > $outfile2
有没有办法用sed 做到这一点?请记住,该文件非常大(超过 5000 万行)。我通过多行搜索找到了this blog,我可以尝试,但如果我理解正确,这会在搜索之前将所有行连接到保持缓冲区中,而我对sed 的了解不够知道这是否是一个非常糟糕的主意,超过 5000 万行。
单行文件:
我尝试使用一个 sed 脚本使用单行文件一步完成所有操作,但最终我只得到了最后一个匹配项作为输出。这是我为此使用的sed 脚本:
sed -n -e 's/^.*<object uid="\([-0-9]*\)"><name>\([^<]*\)<.*/\1 \2/p' $infile > $outfile
我想我知道为什么这个表达式不起作用(开头和结尾的 .* 匹配我想要的数据之前/之后的所有内容),但我无法修复它。我已经尝试了表达式的一些变化,但我从来没有得到我正在寻找的结果。它要么只打印最后一个结果,要么打印整行(在这种情况下是整个文件)。如何从单行文件中解析出每个匹配项?
【问题讨论】: