0

egrepを使用して、非常に長いファイル (100 万行) 内の複数の文字列の正確な一致を探します。

egrep "\<string1\>|<\string2\>" my_file

しかし、たった 2 つの文字列を見つけるだけでも時間がかかりすぎます。オカレンスが見つかった場合でも、ファイルの合計行に沿ってすべての文字列を探すようです。実際、ファイルには各文字列が 1 回だけ含まれていることがわかっています。それから、文字列の出現を見つけたら、egrep に文字列の検索を停止させ、リストの次の文字列を探すように強制する方法を知りたいです。または、それを効率的に行う別の方法がある場合。

ありがとう。

4

3 に答える 3

2

-m一致の数を制限するオプションがあります:

-m NUM, --max-count=NUM
     Stop reading a file after NUM matching lines.

ただし、複雑なパターンで直接使用することはできません。これは、すべてのサブパターンに対して 1 行しか得られないためです。あなたができることは、サブパターンを呼び出してループすることですfgrep -m 1:

for pat in $patterns; do
    fgrep -m 1 $pat my_file
done

PS 別のオプションは、複雑なパターンを使用して、サブパターンの数と同じ数の一致を指定することですが、各ファイル行の比較が遅くなります。

于 2012-10-05T14:45:48.583 に答える
2

検索を最適化する方法は、grep 実装で使用するアルゴリズムによって異なります。egrep の「伝統的な」アルゴリズムは、パターンを決定論的有限オートマトンにコンパイルすることです。それが何かわからなくても、心配しないでください: 重要なことは、コンパイルには少し時間がかかるということですが、一度完了すると非常に高速であり、その速度は探しているパターンの複雑さに依存しません。為に。実際、コンパイルが完了すると、egrep は実際には fgrep よりも高速です。つまり、小さなファイルでは fgrep が最速であり、大きなファイルでは egrep が最速です。

少なくとも、[ef]grep の従来の実装ではこのような状況です。最新の実装のほとんどは適応的で、状況に応じてアルゴリズムを切り替えると思います (たとえば、最新の fgreps は、十分な大きさのファイルに対してコンパイル済みの DFA モードに切り替えると思います)。あなたの実装にとって最速のものを見つけるには、いくつかの時間制限のある実験を実際に試す必要があります。

ただし、いくつかの推奨事項をお伝えできます。まず、検索を複数回実行しないようにします (たとえば、単語ごとに fgrep を実行する)。これは、ファイルを複数回スキャンすることを意味します。第二に、検索する文字列の数を最小限に抑えることについて心配する必要はありません。3 番目に、@Lev の提案を使用-mして、必要なものが見つかった後に停止させます (ただし、両方の単語を で 1 回検索することになると確信しています-m2)。

于 2012-10-06T01:56:28.140 に答える
1

よくわかりませんが、おそらくこれはより高速です:

grep -e '<pattern1>' -e '<pattern2>' -e '<pattern3>' your_file

-Fあなたのパターンは実際にはパターンではないと思います。また、出力が色付きの場合、grepはすべてのパターンを探すしかないと思います。

于 2012-10-05T14:38:26.110 に答える