解析xml并将数据放入bash数组中

时间:2012-12-21 04:30:25

标签: bash shell unix

我有以下xml。我想遍历每个节点并推送<url>

如果<extern> == 1,请将

值转换为bash数组。知道我应该如何处理这个问题吗?

<GraphXML>
      <graph isDirected="true">
        <node name="0">
          <label>font</label>
          <url>http://fonts.googleapis.com/css?</url>
          <data>
            <checktime>0.262211</checktime>
            <extern>1</extern>
          </data>
        </node>
        <node name="1">
          <label>logo</label>
          <url>http://example.com/example.png</url>
          <data>
            <dlsize>7545</dlsize>
            <checktime>0.280600</checktime>
            <extern>0</extern>
          </data>
        </node>
     </graph>
    </GraphXML>

2 个答案:

答案 0 :(得分:2)

使用xmllint:

out=$(echo "cat /GraphXML/graph/node/url|/GraphXML/graph/node/data/extern" | \
        xmllint --shell input | sed 's/<[^>]*>//g;s/[-][-]*//g;s/\/[^>]*>//')
set $out
i=0
while [ $#  -gt 0 ] ; do
  url=$1
  shift
  extern=$1
  shift
  if [ $extern -eq 1 ]; then
    array[$i]=$url
    let i++
  fi  
done

echo ${array[*]}

答案 1 :(得分:1)

使用bash

#!/bin/bash
declare -a ARR
while read -r line; do
    if [[ "$line" =~ ^\<(url|extern)\>(.*)\</[^\>]*\>$ ]]; then
        if [ "${BASH_REMATCH[1]}" == "extern" ]; then
            (( ${BASH_REMATCH[2]} == 0 )) && unset ARR[${#ARR[@]}-1]
        else
            ARR+=("${BASH_REMATCH[2]}")
        fi
    fi
done < <(grep -oE '<(url|extern)>.*</(url|extern)>' file.xml)

echo "${ARR[@]}"

<强>解释

  • grep -oE - 使用扩展正则表达式-E匹配urlextern并返回匹配-o
  • done < <( - 使用Process Substitutiongrep投放到while循环中。
  • while read -r line - 读取一行,直到EOF然后while退出。
  • ^\<(url|extern)\>(.*)\</[^\>]*\>$ - 匹配行并保存到BASH_REMATCH数组。
  • unset ARR[${#ARR[@]}-1] - 如果extern属性值为0,则删除数组中的最后一个元素。
  • ARR+=(...) - 将新元素添加到数组的简短形式。