GNU grepの最適化

GNU grepの最適化

私はgrep -EPATTERNファイルにegrep()を使用します。 (-f path/to/file)。

これはテキストストリームの無限ループで行われます。つまり、すべての入力を一度に集めてgrepに渡すことはできません(例*.log:)。

grepに次の実行のためにPATTERNファイルで構築されたNFAを「保存」させる方法はありますか?

Googleを検索してドキュメントを読みましたが、運がありません。

もう少し詳しく説明します。 IPアドレス、ドメインなどの固定数の文字列を見つけるには、正規表現を使用する必要があります(これは質問の一部ではありませんが、自由に異なるものを提案できます)。検索はインターネットフィードに基づいて行われました。テキストの流れだと思ってください。grepストリームなので、すべての入力は使用できません。ストリームの塊を蓄積してgrep使用できますが(grepすべての行には使用できません)、それも制限されます(30秒だとします)。

grepNFAがすべてのスキーマ(私の場合はファイル)で構築されていることを知っています。だから私の質問は、grepこのNFAは変更されないので、次の実行のために保存するように言うことができますか?これにより、毎回NFAを構築するのに時間が節約されます。

ベストアンサー1

いいえ、そんなことはありません。一般に、開始コストgrep(新しいプロセスフォーク、実行可能ファイルのロード、共有ライブラリ、動的接続...)は正規表現をコンパイルするよりもはるかに高いため、この最適化はほとんど意味がありません。

見たけど1250個の文字列を90kパターンに一致させるのはなぜそんなに遅いのですか?grepいくつかの正規表現を特に遅くするいくつかのGNUバージョンのバグについてです。

grepここでは、ブロックを同じインスタンスに提供することで、ブロックを複数回実行することを避けることができますgrep。以下以外のzshGNUgrepと実装を使用してください。awkmawk

coproc grep -E -f patterns -e '^@@MARKER@@$' --line-buffered
process_chunk() {
  { cat; echo @@MARKER@@; } >&p & awk '$0 == "@@MARKER@@"{exit};1' <&p
}
process_chunk < chunk1 > chunk1.grepped
process_chunk < chunk2 > chunk2.grepped

awkorを使用してすべての操作を実行する方が簡単かもしれませんperl

grepただし、出力を別のチャンク内の他のファイルに入れる必要がない場合は、いつでも次のことができます。

{
  cat chunk1
  while wget -qO- ...; done # or whatever you use to fetch those chunks
  ...
} | grep -Ef patterns > output

おすすめ記事