我有两个简单的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
我工作但是当行数很大时它很慢。我需要一个更好的方法来做到这一点。
答案 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
我不是那个曾经用过那个漂亮的小工具的超级用户,但它值得指点。