一致する文字列間の行をフィルタリングする

一致する文字列間の行をフィルタリングする

ファイルに以下のような内容があります。START と END の間には多くの行があり、エラーや警告もあるかもしれません。START と END の間にあるエラーや警告の行をフィルターし、ない場合はスキップします。見出しは名前によって異なります。ただし、START の次の行 (見出しであるはずです) を印刷するロジックを作成します。

START
Heading1
.......
errors
........
END

START
Heading2
........
........
........
END

START
Heading3
.......
errors
Warning...
END

予想される出力は以下のとおりです

Heading1
errors

Heading3
errors
Warning...

以下を試してみましたが、STARTとENDの間のすべてが印刷されます。エラーも除外する必要があります

awk '/START/,/END/' file

答え1

試す:

$ awk 'f{hdg=$0; f=0} /errors|warning/{if(hdg){print hdg; hdg=""}; print} /START/{f=1}' file
Heading1
errors
Heading3
errors

使い方

  • f{hdg=$0; f=0}

    が true (ゼロ以外) の場合f、現在の行を変数に保存しhdgfゼロに戻します。

  • /errors|warning/{if(hdg){print hdg; hdg=""}; print}

    現在の行にerrorsまたは が含まれておりwarning、変数hdgが空でない場合はそれを出力します。また、現在の行も出力します。

  • /START/{f=1}

    現在の行に が含まれている場合START、変数をf1 に設定します。

複数行バージョン

コマンドを複数行に分散することを好む人向け:

awk '
   f {
      hdg=$0
      f=0
   }
   /errors|warning/{
      if(hdg){
         print hdg
         hdg=""
      }
      print
   }
   /START/{
      f=1
   }' file

バリエーション: 見出しの前に空白行を追加する

出力を区切るために空行を入れたい場合:

$ awk 'f{hdg=$0; f=0} /errors|warning/{if(hdg){print nl hdg; hdg=""; nl="\n"}; print} /START/{f=1}' file
Heading1
errors

Heading3
errors

バリエーション: END行の後のエラー/警告を無視する

$ awk 'f{hdg=$0; f=0} g && /errors|warning/{if(hdg){print nl hdg; hdg=""; nl="\n"}; print} /START/{f=1; g=1} /END/{g=0}' file
Heading1
errors

Heading3
errors

上記の大文字と小文字を区別しないようにするには (GNU awk):

awk 'BEGIN{IGNORECASE=1} f{hdg=$0; f=0} g && /errors|warning/{if(hdg){print nl hdg; hdg=""; nl="\n"}; print} /START/{f=1; g=1} /END/{g=0}' file

関連情報