XMLから属性値を抽出する

XMLから属性値を抽出する

強い打撃を使用し、

文書:

<?xml version="1.0" encoding="UTF-8"?>
<blah>
    <blah1 path="er" name="andy" remote="origin" branch="master" tag="true" />
    <blah1 path="er/er1" name="Roger" remote="origin" branch="childbranch" tag="true" />
    <blah1 path="er/er2" name="Steven" remote="origin" branch="master" tag="true" />

</blah>

私は以下を試しました:

grep -i 'name="andy" remote="origin" branch=".*\"' <filename>

ただし、行全体を返します。

<blah1 path="er" name="andy" remote="origin" branch="master" tag="true" />

以下に基づいて行を一致させたい。

name="andy"

私はそれが戻ってほしいと思います:

master

答え1

XMLパーサーを使用してXMLデータを解析します。そしてこれは単にXPathの練習になります。

$ branch=$(xmlstarlet sel -t -v '//blah1[@name="andy"]/@branch' file.xml)
$ echo $branch
master

答え2

そしてgrep

grep -Pio 'name="andy".*branch="\K[^"]*' file
  • -PPerl正規表現を有効にする(PCRE)
  • -i大文字と小文字を無視
  • -o一致する部分のみ印刷

正規表現では、\K幅がゼロの反転を使用して前の部分を一致させますが、一致には\K含めません。

答え3

xmllintを使用してXPathを介して属性値を抽出します。

xmllint --xpath 'string(/blah/blah1[@name="andy"]/@branch)' file.xml

属性の順序が変更され、改行が挿入され、名前と分岐属性がファイルの別の行にある可能性があるため、XMLパーサーを使用してXMLを処理するのが最善です。

答え4

私はこれがうまくいくと思います:

$ grep -i 'name="andy" remote="origin" branch=".*\"' <filename> | awk -F' ' '{print $5}' | sed -E 's/branch=\"(.*)\"/\1/'
master

このawkセクションでは、二重引用符と参照の間の内容(括弧の間の部分一致と一致)のみがbranch="master"返されるようにします。sed\1

ここで、awkとsedの技術についてもっと知っている人が多いことがわかっているので、批判を受ける準備ができています。 :-)

関連情報