ターミナルでマルチスレッドgrepを起動する方法は?


38

それぞれ2 GBの250以上のファイルがあるフォルダーがあります。それらのファイルで文字列/パターンを検索し、結果をファイルに出力する必要がありoutputます。私は次のコマンドを実行できることを知っていますが、遅すぎます!!

grep mypattern * > output

スピードアップしたいです。Javaのプログラマーである私は、プロセスを高速化するためにマルチスレッドを使用できることを知っています。grep「マルチスレッドモード」で起動し、出力を1つのoutputファイルに書き込む方法に固執しています。




1
確実に大量のファイルのコレクションを検索することは、IOバウンドの問題の典型的な例です。したがって、複数のスレッドを使用しても役に立ちません。
ジョナサンハートリー

回答:


31

これには2つの簡単な解決策があります。基本的に、xargsまたはを使用しparallelます。

xargsアプローチ:

あなたは使うことができxargsfind、次のように:

find . -type f -print0  | xargs -0 -P number_of_processes grep mypattern > output

起動するnumber_of_processesプロセスの最大数で置き換える場所。ただし、これは、パフォーマンスがI / O制限されている場合に重要なパフォーマンスを提供することを保証するものではありません。この場合、I / Oの待機時間の損失を補うために、より多くのプロセスを開始しようとする場合があります。

また、findを含めると、変更時間などのファイルパターンだけでなく、より高度なオプションを指定できます...

Stéphaneのコメントで説明されているように、このアプローチで考えられる問題の1つは、ファイルが少ない場合、xargs十分な数のプロセスを開始できない可能性があることです。解決策の1つは、-nオプションを使用xargsして、一度にパイプから取得する引数の数を指定することです。設定-n1するとxargs、各ファイルごとに新しいプロセスが強制的に開始されます。これは、ファイルが非常に大きく(この質問の場合のように)、ファイルの数が比較的少ない場合に望ましい動作です。ただし、ファイル自体が小さい場合、新しいプロセスを開始するオーバーヘッドにより、並列処理の利点が損なわれる可能性-nがあります。この場合、値が大きいほど優れています。したがって、-nファイルのサイズと数に応じてオプションを微調整することができます。

並列アプローチ:

別の方法は、Ole Tange GNU Parallel toolを使用することですparallelこちらから入手できます)。これにより、並列処理をよりきめ細かく制御でき、複数のホストに分散させることもできます(たとえば、ディレクトリを共有する場合に役立ちます)。パラレルを使用した最も単純な構文は次のとおりです。

find . -type f | parallel -j+1 grep mypattern

このオプション-j+1は、マシンのコア数を超える1つのプロセスを開始するように並列に指示します(これは、I / Oの制限されたタスクに役立つ場合があります。

Parallelには、xargs各プロセスからの出力の順序を実際に保持し、連続した出力を生成するという利点もあります。たとえば、xargsプロセス1が行を生成する場合p1L1、プロセス2が行を生成しp2L1、プロセス1が別の行を生成するp1L2場合、出力は次のようになります。

p1L1
p2L1
p1L2

一方parallel、出力では次のようになります。

p1L1
p1L2
p2L1

これは通常、xargs出力よりも便利です。


1
おそらくと-n組み合わせて使用したいと思うでしょう-P。そうしxargsないと、ファイルが2つしかない場合、複数のプロセスが生成されない場合があります。
ステファンシャゼラス

1
さて、-n1はgrepファイルごとに1 つ開始します。ファイルが非常に大きく、その数が非常に少ない場合を除き、ファイルを検索する代わりにgrepプロセスの開始と停止に時間を費やすので、おそらくそれを少し増やしたいと思うでしょう。
ステファンシャゼル

9

CPU単位でgrepを高速化するには、少なくとも2つの方法があります。

  • 正規表現ではなく固定文字列を検索する場合は、-Fフラグを指定します。

  • パターンがASCIIのみの場合、UTF-8の代わりに8ビットロケールを使用します(例:)LC_ALL=C grep ...

ただし、ハードドライブがボトルネックの場合、これらは役に立ちません。その場合、おそらく並列化も役に立たないでしょう。


1
man grep「egrepまたはfgrepのいずれかとしての直接呼び出しは非推奨ですが、それらに依存する履歴アプリケーションを変更せずに実行できるようにするために提供されています」で見ました。これが本当に重要かどうかはgrep -F
わかり

1
また、「パターンではなく」と言うとき、正規表現を参照していますか?
-iyrin

「ASCIIのみ」の検索では、CPUが大幅に削減されます。ただし、stackoverflow.com
a / 11777835/198219の

3

問題がI / Oバウンドではない場合、マルチコア処理用に最適化されたツールを使用できます。

ふるい(http://sift-tool.org、免責事項:私はこのツールの著者です)またはシルバーサーチャー(https://github.com/ggreer/the_silver_searcher)をご覧ください

単純な文字列検索ではなく正規表現パターンを使用する場合、シルバーサーチャーのファイルサイズ制限は2GBです。


確かに大量のファイルを検索することは、IOバウンドの問題の典型的な例ですか?
ジョナサンハートリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.