Bash - 从XML中提取数据

时间:2016-04-14 18:33:57

标签: xml bash

请参阅下面的XML示例。

使用bash脚本,如何将XML文件中所有“from”标记之间的字符串解压缩为数组? 即像阵列= [Ben,Jani,James,Harry,...]

示例XML文件:

<note>
<to>Tove</to>
<from>Ben</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
<note>
<to>Tove</to>
<from>James</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

3 个答案:

答案 0 :(得分:0)

编辑:@jil告诉我,我的初始解决方案仅在XML文件格式化为OP粘贴时才有效,但如果每行有多个<from>标记则失败。以下代码修复了该问题,因为它首先删除了所有新行字符:

#!/bin/bash

NAMES=()
one_line=$(sed "s/\n//g" file.xml)
from_names=$(echo $one_line | grep -Po "<from>(.*?)<\/from>")

for word in $from_names
do
    name=$(echo $word | sed -n "s/<from>\(.*\)<\/from>/\1/p")
    NAMES+=($name)
done

echo ${NAMES[@]}

然后,您可以引用每个名称,例如${NAMES[0]}${NAMES[1]}${NAMES[2]}等。

脚本末尾的

echo ${NAMES[@]}打印出列表中的所有元素,非常适合测试。

答案 1 :(得分:0)

这不是xml感知命令,期望标记位于每个单独的行上。

$ arr=$(sed -rn 's_<from>(.*)</from>_\1_p' xml)
$ echo ${arr[@]}
Ben Jani James

答案 2 :(得分:-1)

您想使用某些XML shell工具,例如 xmlstarlet xmllint xpath (来自XML :: XPath Perl模块)。< / p>

E.g。使用 xpath

array=( $(xpath -q -e "//from/text()" input_file.xml) )

使用 xmllint sed

array=( $(xmllint --xpath '//from' input_file.xml \
          | sed 's#</\?from># #g') )

P.S。您的样本输入格式不正确(缺少根元素)