我在一个目录中有多个XML文件,我想从中提取不同类型的数据到一个类似于表的输出(字段之间的选项卡)。 此外,我想有标题(列名),以及一些列中的布尔插值。
我准备了2个样本XML文件,可以在下面找到,我希望有一个AWK命令,它将运行该目录中的所有文件,并提取以下值:
字符串“$ test2 $”,如果存在
在真实目录中,我有200多个文件,我希望所有这些文件都能在输出中表示,即使其中一些文件没有任何上述值。
< / LI>请注意,值“$ test1 $”和“$ test2 $”位于不同的父元素下。 “property1”和“property2”元素(上面列表中的#2和#3)将始终保持不变,但不一定按相同的顺序排列(如下面的输入文件所示)。
我知道如何使用文件名和上面列表中的其他值之一(使用AWK中的FILENAME内置参数)获取所需的输出,但是我似乎无法正确添加其他值。
据我所知,AWK是用于此类事情的最佳工具,但是如果你想到另一种能提供相同输出的工具,那么我对它的确比较好:-)
请在下面找到XML文件(输入数据):
TextXML1.xml:
<?xml version="1.0" encoding="UTF-8"?>
<TestXML1>
<properties>
<property name="property1" value="500"></property>
<property name="property2" value="true"></property>
</properties>
<attrs>
<attr type='parameter' name='T1234'>
<parameter input='$test1$'></parameter>
</attr>
<attr type='parameter' name='H5H7'>
<parameter input='$test2$'></parameter>
</attr>
</attrs>
</TestXML1>
TestXML2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<TestXML2>
<properties>
<property name="property2" value="False"></property>
<property name="property1" value="300"></property>
</properties>
<attrs>
<attr type='parameter' name='TD837'>
<parameter input='$test1$'></parameter>
</attr>
<attr type='parameter' name='JQE284'>
<parameter input='$test3$'></parameter>
</attr>
</attrs>
</TestXML2>
所需的输出:
File name property1 property2 $test1$ $test2$
TestXML1.xml 500 True True True
TestXML2.xml 300 True True False
非常感谢!
答案 0 :(得分:1)
以下是如何使用GNU awk为第3个arg提取所有名称,值和输入以匹配()和真正的多维数组:
$ cat tst.awk
match($0,/\<name="([^"]*)".*\<value="([^"]*)"/,a) { n2v[a[1]][ARGIND] = a[2] }
match($0,/\<input=\047([^\047]*)\047/,a) { inputs[a[1]][ARGIND] }
END{
printf "Filename"
for (name in n2v) {
printf "%s%s", OFS, name
}
for (input in inputs) {
printf "%s%s", OFS, input
}
print ""
for (fileNr=1; fileNr<ARGC; fileNr++) {
printf "%s", ARGV[fileNr]
for (name in n2v) {
printf "%s%s", OFS, (fileNr in n2v[name] ? n2v[name][fileNr] : "N/A")
}
for (input in inputs) {
printf "%s%s", OFS, (fileNr in inputs[input] ? "True" : "False")
}
print ""
}
}
$ awk -f tst.awk TestXML1.xml TestXML2.xml
Filename property1 property2 $test1$ $test2$ $test3$
TestXML1.xml 500 true True True False
TestXML2.xml 300 false True False True
您可以轻松调整它,只选择您关心的那些。
答案 1 :(得分:0)
正如其他人已经指出的那样,你不应该使用像awk
这样的面向行的工具来处理XML。请使用类似xmlstarlet
的XML感知工具。这是您问题的部分解决方案:
xmlstarlet sel -t -v //property/@value -nl -v //parameter/@input -nl TestXML1.xml TestXML2.xml