XML コンテキストの grep

XML コンテキストの grep

以下は私のファイルの内容です。

<A>
<number>100</number>
<name>Word1</name>
</A>
<A>
<number>101</number>
<name> Word2</name>
</A>

をgrepするとWord1、以下のような出力が表示されます。

<A>
<number>100</number>
<name>Word1</name>
</A>

をgrepするとWord2、以下のような出力が表示されます。

<A>
<number>101</number>
<name>Word2</name>
</A>

誰かこれを手伝ってくれませんか?

答え1

これが適切に形成された XML ドキュメントの一部である場合は、XML パーサーを使用して必要な部分を抽出できます。

満足するために整った要件に従って、XML フラグメントを および でラップしまし<root></root>

xmlstarlet sel -t -c '//A[name="Word1"]' -n file.xml

これを直接満たすことができない場合は、明示的にラップすることができます

( echo '<root>'; cat file.xml; echo '</root>' ) | xmlstarlet sel -t -c '//A[name="Word1"]' -n

どちらの場合でも、出力は次のようになります。

<A>
<number>100</number>
<name>Word1</name>
</A>

答え2

pcregrep

<file.xml pcregrep -Mo '(?s)<A>(?:.(?!</A>))*Word1.*?</A>'

GNUの場合grep:

<file.xml grep -zPo '(?s)<A>(?:.(?!</A>))*Word1.*?</A>' | tr '\0' '\n'

(ただし、これはファイル全体がメモリにロードされ、NUL バイトが含まれていないことを前提としていることを意味します)。

いくつかの PCRE 演算子:

  • (?s)フラグをオンにしますs.行区切り文字に一致します)
  • .(?!</A>)の先頭でない限り、任意の文字を使用できます</A>
  • .*?非貪欲版.*
  • (:...)グループ化するだけです。

またはのような要素によって騙され、またはとして表現される<![CDATA[</A>]]>が見つからないため、XML パーサーが必要になります。しかし、XML パーサーには有効な XML 入力が必要ですが、サンプルは最上位の要素で囲まない限りは有効な XML 入力ではありません。また、ファイル全体を読み込む必要があり (ただし、その形式で作業する場合は通常これが一般的です)、コンテンツが変換される可能性があります (および一部のシーケンスを展開します)。また、xpath 式では、コメントや XML タグまたは属性を含むどこでもそれらを見つけることが困難になります。Word2<![CDATA[W]]>ord2>&#87;ord2<![CDATA&...;Word1

関連情報