1

次のxmlがあります。各ノードをループしてプッシュしたい<url>

== 1の場合、値をbash配列に入れ<extern>ます。これにどのようにアプローチすべきか考えていますか?

<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>
4

2 に答える 2

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[*]}
于 2012-12-21T04:56:53.230 に答える
1

バッシュの使用

#!/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- 拡張正規表現を使用して or の-Eいずれurlかに一致し、一致externを返します-o
  • done < <(-プロセス置換を使用してループにフィードgrepします。while
  • while read -r lineEOF- 終了するまで1 行読み取りwhileます。
  • ^\<(url|extern)\>(.*)\</[^\>]*\>$- 行を一致させてBASH_REMATCH配列に保存します。
  • unset ARR[${#ARR[@]}-1]- extern 属性値が 0 の場合、配列の最後の要素を削除します。
  • ARR+=(...)- 新しい要素を配列に追加するための短縮形。
于 2012-12-21T07:42:29.100 に答える