250を超えるファイルを含むフォルダがあり、各ファイルのサイズは2 GBです。このファイルから文字列/パターンを検索し、結果をファイルに出力する必要がありますoutput
。次のコマンドを実行できることを知っていますが、遅すぎます!
grep mypattern * > output
仕事のスピードを上げたいです。 Javaプログラマーとして、私はマルチスレッドを使用してプロセスをスピードアップできることを知っています。grep
「マルチスレッドモード」で起動し、出力を単一のファイルに書き込む方法を心配していますoutput
。
ベストアンサー1
2つの簡単な解決策があります。デフォルトでxargs
またはを使用しますparallel
。
xargs メソッド:
xargs
次のように使用できますfind
。
find . -type f -print0 | xargs -0 -P number_of_processes grep mypattern > output
number_of_processes
ここで開始するプロセスの最大数を上書きします。ただし、パフォーマンスがI / Oバインドされている場合、かなりのパフォーマンスを保証することはできません。この場合、I / Oを待っている間に失われた時間を補償するために、より多くのプロセスを開始しようとすることがあります。
また、検索を含めると、変更時間などのファイルモードよりも高度なオプションを指定できます。
Stéphaneのコメントによると、このアプローチの1つの可能な問題は、ファイルがほとんどないと、xargs
そのファイルに対して十分なプロセスを開始できない可能性があることです。 1つの解決策は、-n
オプションを使用して、xargs
一度にパイプラインから取得する必要があるパラメータの数を指定することです。この設定は、各ファイルに対して新しいプロセスを-n1
強制的にxargs
開始します。これは、ファイルが非常に大きく(この質問の場合)、ファイル数が比較的少ない場合に望ましい動作です。ただし、ファイル自体が小さい場合は、新しいプロセスを開始するためのオーバーヘッドが並列性の利点を打ち消す可能性があります。この場合、-n
大きな値が優れています。したがって、-n
このオプションはファイルのサイズと数に応じて細かく調整できます。
並列アプローチ:
もう1つの方法は、Ole Tange GNU Parallelツールparallel
(使用可能)を使用することです。ここ)。これにより、並列処理をより細かく制御でき、複数のホストに分散することができます(たとえば、ディレクトリを共有する場合に便利です)。並列性を使用する最も簡単な構文は次のとおりです。
find . -type f | parallel -j+1 grep mypattern
このオプションは、-j+1
マシンのコア数を超える1つのプロセスを並列に開始するように指示する場合(これはI / O制限操作に役立ち、数を増やすこともできます)。
xargs
並列性は、実際には各プロセスの出力順序を保存し、順次出力を生成するという利点もあります。たとえば、xargs
プロセス 1 が 1 行を生成しp1L1
、プロセス 2 が 1 行を生成しp2L1
、プロセス 1 が別の行を生成する場合、p1L2
出力は次のようになります。
p1L1
p2L1
p1L2
そしてparallel
出力は次のようになります。
p1L1
p1L2
p2L1
これはしばしば出力よりも便利ですxargs
。