Bash:将XML块解析为数组

时间:2012-11-19 15:49:57

标签: xml arrays bash parsing

我有一个类似xml的文本文件,我想解析成一个数组。输入文件如下所示

<AA>
  <BB>content 1</BB>
</AA>
<AA>
  <BB>content 2</BB>
</AA>

我希望输出像(意味着每个数组元素一个整个AA块):

ARRAY[0]=<AA><BB>content 1</BB></AA>
ARRAY[1]=<AA><BB>content 2</BB></AA>

我试过

ARRAY=(`cat input.txt | grep -A 3 \<AA\>`)

但这只返回每个数组元素一行。有没有人有想法?

4 个答案:

答案 0 :(得分:3)

XML和shell脚本混合得不是很好。如果可以,请考虑使用不同的文件格式或不同的脚本语言。

(
    IFS=$'\n'
    ARRAY=($(grep -A 3 '<AA>' test.xml | awk '{printf "%s",$0} $0~"</AA>" {print}'))

    for MATCH in "${ARRAY[@]}"; do
        echo "$MATCH"
    done
)

说明:

  1. 将IFS设置为\n可控制如何拆分数组元素。我们不希望它们在空格或制表符上分割,只是换行。
  2. ARRAY=($(COMMAND))捕获COMMAND的输出并将每一行作为数组元素(因为我们将IFS设置为\n)。
  3. {printf "%s",$0}打印每一行,不带尾随换行符。
  4. 每当我们看到结束标记$0~"</AA>" {print}时,
  5. </AA>就会打印换行符。
  6. 整个事情在括号中限制$IFS更改的范围。我们不希望这种改变是永久性的;最好将其限制为子壳。

答案 1 :(得分:1)

sed '/^<AA>$/,/^<[/]AA>$/{H;/<[/]AA>/{s:.*::g;x;s:\n::g;s:[ ]*<B:<B:g;b};d}' FILE

答案 2 :(得分:1)

如果您的XML是well-formed,则以下示例演示了如何使用xpath正确解析它:

#!/bin/bash

XML="
<doc>
<AA>
  <BB>content 1</BB>
</AA>
<AA>
  <BB>content 2</BB>
</AA>
</doc>
"

CONTENT1=`echo $XML | xmllint --xpath "string((/doc/AA/BB)[1])" -`
CONTENT2=`echo $XML | xmllint --xpath "string((/doc/AA/BB)[2])" -`

echo $CONTENT1
echo $CONTENT2

答案 3 :(得分:0)

假设<AA></AA>是固定名称,这里是一个纯粹的bash解决方案

#!/bin/bash
declare -a ARRAY
while read -r line; do
    [ "$line" =~ ^\<BB\>$ ] && ARRAY+=("<AA>$line</AA>")
done < file.xml