大きなファイル(スレッドダンプ)があります。名前付きスレッドが複数あり、待機して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 を使用します。詳しくは、その他の関連用語をご覧ください。