同じ行(AND条件)にないブロック内で2つの文字列を見つけ、同じブロック内で別の内容を見つける方法

同じ行(AND条件)にないブロック内で2つの文字列を見つけ、同じブロック内で別の内容を見つける方法

grep2つの文字列が同じ行に表示されない場合は、ブロック内でAND条件を使用して2つの文字列を表す方法を知りたいです。次の試みたが同じ行にない文字列では機能しません。

  1. grep 'string1.*string2\|string2.*string1' filename
  2. grep -P '^(?=.*pattern1)(?=.*pattern2)' filename

たとえば、次の行を含むxmlファイルがあります。

  <test-result
    exectime="2017-07-07"
    result="FAILURE"
    isdone="TRUE"
    logicalname="this.is.test1"
    duration="10050"
  >
    <test-case
      testcasename="this.is.test.case.name1"
      testunit="abcd-mc"
      testpath="file:/this/is/the/file/path1/abcd.xml"
     >
     </test-case>

    </test-result>

 <test-result
      exectime="2017-07-07"
      result="SUCCESS"
      isdone="TRUE"
      logicalname="this.is.test1"
      duration="10050"
     >
    <test-case
     testcasename="this.is.test.case.name1"
     testunit="abcd-mc"
     testpath="file:/this/is/the/file/path1/uvwx.xml"
    >

   </test-case>
  </test-result>

タグの中には2つのコードブロックが<test-result></test-result>あるので、同じブロックに対応する値をAND(AND)で探したいとtestpath思います。greplogicalnameresultgrep this.is.test1FAILUREtestpath

testpath次に、シーンがある場合、結果は"私が見つけた"と?にFAILURE合わせてファイルを変更するには?SUCCESStestpathlogicalname

ベストアンサー1

私の提案は「そうしようともしないでくださいgrepawkまたは、いくつかの奇妙な正規表現ベースのハッキングを削除することができますが、正規表現perlはそうではありません。安定してXMLからデータを解析または抽出するために使用されます。何を考えても読めず、メンテナンスも不可能な混乱になる可能性が高いです。より良い方法があります。実用的で効果的で信頼できる方法です。

つまり、XMLやHTMLを解析しないでください。正規表現の使用。それ動作しません

代わりに、次のXMLパーサーを使用してください。xmlstarlet。または、選択できる複数のXML構文解析ライブラリがある言語perlまたは同じ言語を使用してください。python

grep行ベースのツール(またはより良い方法awkperlさらには)を使用してXMLを処理するには、sedまず次のようにxmlを行ベースの形式に変換します。XML2。これは、XMLファイルから非常に単純なデータ抽出に適した選択です。

たとえば、サンプルXMLで最も明白なエラーを修正した後の外観は次のとおりですxml2

$ xml2 < ajs.xml 
/xml/test-result/@exectime=2017-07-07
/xml/test-result/@result=FAILURE
/xml/test-result/@isdone=TRUE
/xml/test-result/@logicalname=this.is.test1
/xml/test-result/@duration=10050
/xml/test-result/test-case/@testcasename=this.is.test.case.name1
/xml/test-result/test-case/@testunit=abcd-mc
/xml/test-result/test-case/@testpath=file:/this/is/the/file/path1/abcd.xml
/xml/test-result
/xml/test-result/@exectime=2017-07-07
/xml/test-result/@result=SUCCESS
/xml/test-result/@isdone=TRUE
/xml/test-result/@logicalname=this.is.test1
/xml/test-result/@duration=10050
/xml/test-result/test-case/@testcasename=this.is.test.case.name1
/xml/test-result/test-case/@testunit=abcd-mc
/xml/test-result/test-case/@testpath=file:/this/is/the/file/path1/uvwx.xml

ちょうどそれを使って欲しいものを得るのは難しいですが、おそらく使いやすくなりますgrepperlXMLライブラリを使わずに普通のPerl)、それを使うawkのはそれほど難しくありませんsed

またはでXML解析ライブラリを使用する方がxmlstarlet簡単です。これらすべての方法は、XML文書の構造化データと直接機能します。つまり、各XML要素は、任意の方法でリンクできる行の束ではなく、オプションの属性と値を持つ一意のオブジェクトとして扱われます。perlpython

しかし、良い答えがある質問がたくさんあります。xmlstarletそしてXML2このウェブサイトから。

xml2どちらもxmlstarletほとんどのLinuxディストリビューションに事前パッケージされています。

最後に、少なくともよく構造化されたXMLで始めましょう。上記のサンプルXMLにはいくつかの欠陥があります。破損、不完全、または非標準のXML入力を解析するツールは困難です。

おすすめ記事