xmllintとegrepの出力があり、隣接する2つのフィールドを印刷したいと思います。例えば
(xmlinput) xmllint --format | egrep reference\|sourcefile
<reference>ItemX</reference>
<sourcefile>://filepath/blah/blah/</sourcefile>
<reference>ItemY</reference>
<sourcefile>://filepath/blah/blah/</sourcefile>
.
.
<reference>ItemW</reference>
<sourcefile>://filepath/blah/blah/</sourcefile>
参照とソースファイル要素を並べて出力する方法はありますか?例えば
(xmlinput) xmllint --format | egrep reference\|sourcefile
<reference>ItemX</reference><sourcefile>://filepath/blah/blah/</sourcefile>
<reference>ItemY</reference><sourcefile>://filepath/blah/blah/</sourcefile>
.
.
<reference>ItemW</reference><sourcefile>://filepath/blah/blah/</sourcefile>
答え1
[your command] | paste -d '' - -
連続した行をリンクします。
答え2
XML操作を開始すると、入力grep
について仮定し(ほぼ確実に)、もはや有効なXML出力がないため、これが最善の方法ではない場合があります。
つまり、抵抗が最も少ないパスは通常grep
XML(フォーマットが適切な最小例xmllint
これは役に立ちます)、次のように--xpath
(サポートのxmllint
ために> = 2.7.7 --xpath
)利用可能でなければなりません:
xmllint --xpath "//reference|//sourcefile" input.xml |
pcregrep -o "(<reference>.*?</sourcefile>)"
xmllint
抽出された要素を使用するXパス|
関心のある要素の1つと一致する(論理的ORで)式です(//
入力の任意の位置で一致するすべての要素を選択するため)。 (非XML認識)各要素のペアをグループpcregrep
(代わりに)と一致させ、一致する各グループを1行に出力します。ここで注目すべき点はPCREという正規egrep
表現です。.*?
貪欲ではないマッチだから一致する最低限度で一度に全行ではなくラベル間のテキスト量を示します(xmllint --xpath ...
すべてを1行にダンプ)。
grepを使うのはちょっとした「チート」です。入力について仮定しますが、xmllint
ほとんどの重い作業を行います。このアプローチは将来の解析問題を引き起こす可能性があります。XMLは「正常」ではありません正規表現は、操作に最適なツールではありません。
これを行うためのきちんとした方法は次のとおりです。XMLスター:
xml select -t -m '//*' \
--if 'local-name()="reference"' -c . \
--elif 'local-name()="sourcefile"' -c . -o $'\n' input.xml
これはすべての要素(//*
)を検索し、一致する場合は<reference>
ノードを出力(-c .
)にコピーし、そうでない場合は追加の改行<sourcefile>
()を使用してノードを出力にコピーします-o $'\n'
。
答え3
データをパイプで接続するだけです。perl -pe 'chop if /^<reference>/'