強い打撃を使用し、
文書:
<?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データを解析します。そしてxmlstarletこれは単にXPathの練習になります。
$ branch=$(xmlstarlet sel -t -v '//blah1[@name="andy"]/@branch' file.xml)
$ echo $branch
master
答え2
そしてgrep
:
grep -Pio 'name="andy".*branch="\K[^"]*' file
-P
Perl正規表現を有効にする(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の技術についてもっと知っている人が多いことがわかっているので、批判を受ける準備ができています。 :-)