如何在unix中比较和合并两个xml文件

时间:2014-10-29 07:09:09

标签: xml performance unix

我有两个简单的XML文件,并且正在寻找一种比较和合并的简便方法。

文件1 :将具有这样的结构

<lab><id>101</id><name>AAA</name></lab>
<lab><id>102</id><name>AAC</name></lab>
<lab><id>105</id><name>AAB</name></lab>
<lab><id>104</id><name>CCC</name></lab>

文件2 :将具有这样的结构

<drugs><id>101</id><test>bun</test><results>20.45</results></drugs>
<drugs><id>101</id><test>wbc</test><results>20.45</results></drugs>
<drugs><id>101</id><test>rbc</test><results>20.45</results></drugs>
<drugs><id>103</id><test>bun</test><results>20.45</results></drugs>
<drugs><id>103</id><test>crea</test><results>20.45</results></drugs>
<drugs><id>103</id><test>rdw</test><results>20.45</results></drugs>

我希望输出文件看起来像这样

<lab><id>101</id><name>AAA</name></lab>
<drugs><id>101</id><test>bun</test><results>20.45</results></drugs>
<drugs><id>101</id><test>wbc</test><results>20.45</results></drugs>
<drugs><id>101</id><test>rbc</test><results>20.45</results></drugs>

实际上,我使用id进行比较:

while read line
do
          for i in `echo $line | sed -e 's%.*<id>\(.*\)</id>.*%\1%p'`
          do
          if grep -q "$i" file2.xml  ; then
            echo $line >> file3.xml
            grep -i "$i" file2.xml  >> file3.xml
            sed -i "/$i/d" file2.xml
    fi
    break
    done
done < file1.xml

我工作但是当行数很大时它很慢。我需要一个更好的方法来做到这一点。

2 个答案:

答案 0 :(得分:4)

假设您要打印<id>在两个文件中的所有行,这个awk脚本会创建它:

awk -v FS="<id>|</id>" 'FNR==NR {a[$2]=$0; next} ($2 in a) {if (f!=$2) {f=$2; print a[$2]} if (f==$2) {print}}' f1 f2

对于您的样本输入,它返回:

<lab><id>101</id><name>AAA</name></lab>
<drugs><id>101</id><test>bun</test><results>20.45</results></drugs>
<drugs><id>101</id><test>wbc</test><results>20.45</results></drugs>
<drugs><id>101</id><test>rbc</test><results>20.45</results></drugs>

解释

  • -v FS="<id>|</id>"将字段分隔符设置为<id></id>。这样,我们就可以轻松找到id
  • FNR==NR {a[$2]=$0; next}在读取第一个文件(f1)时,将所有行存储在数组a[]中,其索引为<id>值。
  • ($2 in a) {if (f!=$2) {f=$2; print a[$2]} if (f==$2) {print}}在阅读第二个文件(f2)时,打印file1中的相应行或file2中的行,只要它们共享id

答案 1 :(得分:0)

要从命令行操作XML,您可以使用XMLStarlet,它允许您通过XPath查询查询文档,该查询对XML输出格式具有弹性(即,在漂亮打印时它仍然可以工作)。 p>

您要使用的命令是xml sel,例如:

xml sel -t -v "/lab/id" -v "/drugs/id" file1.xml file2.xml

我不是那个曾经用过那个漂亮的小工具的超级用户,但它值得指点。