ファイル内の文字列(文字列には改行/改行が含まれています)を検索し、パターンの一致後に2行を印刷します。たとえば、ファイルには次のものが含まれます。 - (編集済み)
<cfu>
<statm1>
<status>good</status>
</cfu>
<cfu>
<statm2>
<status>not found</status>
</cfu>
<cfu>
<statm3>
<status>empty</status>
</cfu>
<cfa>
<statm1>
<status>good</status>
</cfa>
<cfa>
<statm2>
<status>not found</status>
</cfa>
<cfa>
<statm3>
<status>empty</status>
</cfa>
私は次のことを試しました
awk -v RS=""'/<cfu> <statm1/{i=NR+2}(NR<=i){print}' file_name
しかし運がありません。
期待される出力:-
<cfu>
<statm1>
<status>good</status>
</cfu>
答え1
XMLをデコードせず(とにかく入力がXMLと正確に一致しない)、pcregrep
ultilineM
モードを使用してください。
$ pcregrep -Mo '(?s)<cfu>(?:(?!</cfu>).)*<statm1>.*?</cfu>' your-file
<cfu>
<statm1>
<status>good</status>
</cfu>
(?s)
改行文字も一致させるs
フラグをオンにします。.
(?!</cfu>).
.
前に文字()がありません</cfu>
。私たちはmatch 0以上を使います*
。代わりに、.*
次の終了時間を超えないようにするためにこれを使用してください</cfu>
。*?
はい、貪欲ではないバージョンです*
。
値だけが必要な場合<status>
:
$ pcregrep -Mo1 '(?s)<cfu>(?=(?2)*<status>([^<]*))((?!</cfu>).)*<statm1>.*?</cfu>' your-file
good
答え2
root
ファイルをノードに囲んだ後、正しいHTML / XMLパーサーを使用してください。
そしてxidel
:
xidel --output-node-format=xml -e '//cfu[contains(., "good")]' file
出力:
<cfu>
<statm1>
<status>good
</status></statm1></cfu>
そしてxmlstarlet
:
xmlstarlet format -H file | sponge file
xmlstarlet sel -t -c '//cfu[contains(., "good")]' file 2>/dev/null
出力:
<cfu>
<statm1>
<status>good
</status></statm1></cfu>