ファイル内の各一致に対して現在および次の20行を削除するには何を使用できますか?

ファイル内の各一致に対して現在および次の20行を削除するには何を使用できますか?

大きなファイル(スレッドダンプ)があります。名前付きスレッドが複数あり、待機してmy-thread-\d+いる場合は、その行と次の20行をファイルから削除したいと思います。

たとえば、次のような行があるとします。

"my-thread-1" #628 prio=5 os_prio=0 cpu=54888.61ms elapsed=194386.85s allocated=80325M defined_classes=4 tid=0x00007f406000c9d0 nid=0xb873 waiting on condition [0x00007f3faaeed000] これは私が望んでいない20行です。

このパターンはファイルに複数回表示されます。my-thread-毎回20行を削除するファイルに対してコマンドを実行したいと思いますwaiting on conditon

答え1

そしてawk

awk '/my-thread-[[:digit:]]/ && /waiting on condition/ {skip = 21}
     skip-- <= 0'

スキップされた行内に別の待機スレッドが表示されskipたら、21にリセットされ、そこから21行をスキップします。

以下を使用しますpcregrep(ただし、行内で待機しているスレッドをスキップすることは無視されます)。

pcregrep -Mv 'my-thread-\d.*waiting on condition(.*\n){20}'

答え2

この場合、grepユーティリティはほとんど役に立ちません。以前の行の一致に基づいて行を除外する方法がないためです(-A一部の実装では、利用可能なオプションの意味を一種否定しますgrep)。

私はパターンが再一致することを確認するために、対応する20行を見ずに、一致する行と他の20行をスキップしたいという要求として解釈しました。

これを使用する簡単な方法sedは、次の20行を編集バッファに追加し、入力でトリガーパターンが発生するたびにすべてを削除することです。

sed '/^"my-thread-[[:digit:]]\{1,\}".*waiting on conditon/ { N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;N;d; }' file

私たちは正しいことができますawk

awk '/^"my-thread-[[:digit:]]+".*waiting on conditon/ { for (i=0; i<20; ++i) getline; next }; 1' file

または、今awk行っている行を知っているので、今後20行をスキップできます。

awk 'FNR < skip_to { next } /^"my-thread-[[:digit:]]+".*waiting on conditon/ { skip_to = FNR+21; next }; 1' file

上記のコードでは、FNR現在のファイルの行番号を含む特別な変数です。skip_toこれは、パターンマッチングがトリガーされたときにジャンプしたい行番号です。

答え3

awk '/my-thread-.*waiting on condition/{c=21} !(c&&c--)' file

例えば:

$ seq 20 | awk '/3/{c=6} !(c&&c--)'
1
2
9
10
11
12
19
20

$ seq 20 | awk '/3/{c=11} !(c&&c--)'
1
2

バラより印刷には sed- または awk-a-line-follow-a-matching-pattern を使用します。詳しくは、その他の関連用語をご覧ください。

関連情報