SEDまたはAWKを使用してxmlファイルから2つの異なるパターンに一致する2行のコピー

SEDまたはAWKを使用してxmlファイルから2つの異なるパターンに一致する2行のコピー

次の種類の行を含む大きなxmlファイルがあります。

<test type="one" valid="yes" description="something">
                    twilight-.*\.iso\.auth</test>

<test type="one" valid="no" description="something else">
                    testlite-.*\.cop</test>

<test type="two" valid="yes" description="something else">
                    messing-.*\.cop\.auth</test>
<test type="three" valid="yes" description="something else">messing-.*\.cop\.auth</test>

私のXMLファイルにはこのような行がたくさんあります。私の要件は次のとおりです

  1. 最初の行の "valid="yes"" パターンと 2 行目の ".auth" パターンが一致すると、これら 2 行がコピーされます。 2行目の「.auth」を「.newauth」に置き換えます。
  2. 同じ行で "valid="yes" と ".auth" パターンが一致する場合は、その行をコピーして ".auth" を ".newauth" に置き換えます。

出力は次のようになります。

<test type="one" valid="yes" description="something">
                    twilight-.*\.iso\.auth</test>
<test type="one" valid="yes" description="something">
                    twilight-.*\.iso\.newauth</test>

<test type="one" valid="no" description="something else">
                    testlite-.*\.cop</test>

<test type="two" valid="yes" description="something else">
                    messing-.*\.cop\.auth</test>
<test type="two" valid="yes" description="something else">
                    messing-.*\.cop\.newauth</test>
<test type="three" valid="yes" description="something else">messing-.*\.cop\.auth</test>
<test type="three" valid="yes" description="something else">messing-.*\.cop\.newauth</test>

私のxmlファイルには、置き換える必要がある複数行(ペア)があることに注意してください。ただし、交換規則は上記と同じです。また、4行目の場合は、xmlタグ全体が1行の一部であることに注意してください。したがって、この場合、awk式はやや複雑になります。

よろしくお願いします!

答え1

修正された質問に合わせて更新されました

この試み。 GNU awk 4.2.1ではうまく動作するようです。

awk '/valid="yes"/{print;if(!/<\/test>/){a=$0;getline;print $0"\n"a}gsub(/\.auth/,".newauth")}1' filename

答え2

次のようにエディタを使用してsedこれを簡単に実行できます。

$ sed -e '
    /valid="yes"/!b
    h;/\.auth/G
    /\n/P;//s/.*\n//
    s/\.auth/.newauth/;t
    $q;N;/\.auth/!{P;D;}
    p;s//.newauth/
' test.xml

答え3

@ Steveのソリューションに基づいた2段階のプロセスで、あなたが望むことを達成することができました。

  1. ソリューション#1:
    awk '/valid="yes"/{print;a=$0; next} /.auth/{print $0"\n"a;gsub(/\.auth/,".newauth")}1' test.xml > newtest.xml
  1. 上記の手順のxmlファイルを使用して#2を解決してください。
    awk '/valid="yes"/ && /.auth/{print $0;gsub(/\.auth/,".newauth")}1' newtest.xml > final.xml

これら2つのタスクを1つのawkタスクに結合できますか?

答え4

自分が何をしているのかを知っていて、XMLが他の形式になっていない場合や問題を含めることができない場合は、2つのステップや複雑なスクリプトは必要ありません。これは一度だけ実行できます。

sed -e '/valid="yes"/!b' -e '/\.auth/!N;p;s/\.auth/.newauth/'
  • /valid="yes"/!bパターン()が含まれていない行の場合は、bスクリプトの最後に移動するため、!他のすべての内容はそのまま残ります。
  • /\.auth/!N!()を含まない行に適用されます。この行に ext 行を.auth追加します。N
  • p現在のパターンスペースを印刷します(1行または2行にすることができます)。とにかく必要に応じてコピーする
  • s/\.auth/.newauth/必要な交換を行います。修正されていない行が印刷されましたp。これを繰り返すように変更し、通常の処理が終わると印刷されます。
  • ステップ5?ステップ5はありません。

関連情報