質問
結果から文字列を省略しながら、再帰並列zgrepを実行することはできません。
約640GBの圧縮ファイアウォールログをzgreppingしており、ほぼ30行に「Duplicate SYN」文字列があります(省略しようとしました)。
再帰並列Zgrep(文字列省略なし) - 成功
このような並列再帰 grep を正常に実行できます。
find /var/logs/syslog -name \* -print0 | xargs -0 -n 1 -P 36 zgrep -f foo.txt > /tmp/bar.txt
foo.txtの内容:
10\.10\.0\.28
10\.10\.3\.41
10\.10\.0\.46
10\.10\.5\.47
10\.11\.0\.48
10\.10\.0\.49
10\.144\.41\.145
10\.122\.41\.241
出力例
Apr 18 01:39:33 ASAFW01 : %ASA-4-419002: Duplicate TCP SYN from inside:10.10.0.28/61763 to inside:10.122.41.241/8443 with different initial sequence number
Apr 18 01:39:33 ASAFW01 : %ASA-4-419002: Duplicate TCP SYN from inside:10.10.0.28/61763 to inside:10.122.41.241/8443 with different initial sequence number
May 31 02:58:46 ASAFW01 : %ASA-6-302014: Teardown TCP connection 461681145 for DMZ_EXP_INSIDE:10.122.41.241/7400 to inside:10.5.91.50/30378 duration 0:00:00 bytes 0 Failover primary closed
May 31 02:58:47 ASAFW01 : %ASA-6-302013: Built outbound TCP connection 1962428108 for DMZ_EXP_INSIDE:10.122.41.241/7400 (10.122.41.241/7400) to inside:10.11.0.48/33990 (10.11.0.48/33990)
May 31 02:58:47 ASAFW01 : %ASA-6-302014: Teardown TCP connection 1962428108 for DMZ_EXP_INSIDE:10.122.41.241/7400 to inside:10.11.0.48/33990 duration 0:00:00 bytes 3188 TCP Reset-O from DMZ_EXP_INSIDE
May 31 02:58:49 ASAFW01 : %ASA-6-106015: Deny TCP (no connection) from 10.11.0.48/35976 to 10.122.41.241/7400 flags RST on interface inside
May 31 02:58:49 ASAFW01 : %ASA-6-106015: Deny TCP (no connection) from 10.11.0.48/35976 to 10.122.41.241/7400 flags RST on interface inside
出力を省略したい
Apr 18 01:39:33 ASAFW01 : %ASA-4-419002: Duplicate TCP SYN from inside:10.10.0.28/61763 to inside:10.122.41.241/8443 with different initial sequence number
Apr 18 01:39:33 ASAFW01 : %ASA-4-419002: Duplicate TCP SYN from inside:10.10.0.28/61763 to inside:10.122.41.241/8443 with different initial sequence number
アイデア
- 「Duplicate」という単語を省略する正規表現を使用するようにfoo.txtを変更します(これを行う方法がわかりません)。
- すべての640GB gzip圧縮ログファイルから「Duplicate」という単語を含むすべての行を繰り返し削除します(sedを使用しますか?)
再帰並列Zgrep(文字列省略) - 失敗
ただし、結果から任意の項目を除外しようとするとエラーが発生します。
エラーを引き起こすコマンド:
find /var/logs/syslog -name \* -print0 | xargs -0 -n 1 -P 36 zgrep -f foo.txt -v Duplicate > /tmp/bar.txt
gzip: Duplicate.gz: No such file or directory
gzip: Duplicate.gz: No such file or directory
gzip: Duplicate.gz: No such file or directory
gzip: Duplicate.gz: No such file or directory
gzip: Duplicate.gz: No such file or directory
gzip: Duplicate.gz: No such file or directory
答え1
最も簡単な方法書くgrep
この追加条件は、ファイルに書き込む前に別の呼び出しを介して出力をパイプするだけです。
find /var/logs/syslog -name \* -print0 | xargs -0 -n 1 -P 36 zgrep -f foo.txt | grep -v Duplicate > /tmp/bar.txt
別々のシングルスレッドプロセスでこれを実行するパフォーマンスは、検索によって返されたレコードの数によって異なります。最初の検索と一致する行数が640 GBのログの一部である場合、問題はありません。
基本的な質問は、部分的にこの検索を完全に最適化することに関するものであるため、2つの重要な追加の改善点に言及します。
- grep 検索語として正規表現の代わりに固定文字列を使用します。パターンファイルからバックスラッシュを削除し、
-F
zgrepにスイッチを追加します。 (-w
単語全体に一致するように切り替えるのも良い考えかもしれません。)リテラル文字列を検索する方が正規表現を検索するよりもはるかに高速です。 - システムロケールがUTF-8を使用していてデータセットがASCII専用の場合は、
LC_ALL=C
コマンド環境でこれを設定してください。 128文字のASCIIセットで検索するのは、約1000倍大きいUTF-8文字セットで検索するよりもはるかに高速です。
答え2
GNU Parallelがある場合は、次のことができます。
find /var/logs/syslog -name \* -print0 |
parallel --lb -0 'zgrep -f foo.txt {} | grep -v Duplicate' > /tmp/bar.txt
対照的に、xargs -P
GNU Parallelを使用した出力は行を混在させないことが保証されています(mywiki.wooledge.org/BashPitfalls#Non-atomic_writes_with_xargs_-Pに従って)。