Unix find(1)
ユーティリティは非常に便利で、特定の仕様に一致する多くのファイルに対してアクションを実行できます。
find /dump -type f -name '*.xml' -exec Java -jar ProcessFile.jar {} \;
上記は、特定のディレクトリ内のすべてのXMLファイルに対してスクリプトまたはツールを実行する可能性があります。
私のスクリプト/プログラムが多くのCPU時間を消費し、8つのプロセッサを持っているとしましょう。一度に最大8つのファイルを処理できると便利です。
GNU makeは-j
フラグを使用して並列ジョブ処理を可能にしますが、find
にはそのような機能がないようです。これにアプローチする代替の一般的なジョブスケジューリング方法はありますか?
xargs
と-P
オプション(プロセス数)。 4 CPUマシンのディレクトリにあるすべてのログファイルを圧縮したいとします。
find . -name '*.log' -mtime +3 -print0 | xargs -0 -P 4 bzip2
-n <number>
プロセスごとのワークユニットの最大数。つまり、2500個のファイルがあり、次のように言ったとします。
find . -name '*.log' -mtime +3 -print0 | xargs -0 -n 500 -P 4 bzip2
これは4 bzip2
プロセス。それぞれ500ファイルあり、最初のプロセスが終了すると、最後の500ファイルに対して開始されます。
前の答えがxargs
andmake
を使用する理由がわからない場合、2つの並列エンジンがあります!
GNUパラレル も役立ちます。
find /dump -type f -name '*.xml' | parallel -j8 Java -jar ProcessFile.jar {}
-j8
引数がない場合、parallel
のデフォルトはマシンのコア数になります:-)
find
を「修正」する必要はありません-並列処理にmake
自体を利用します。
プロセスでログファイルまたはその他の出力ファイルを作成し、次のようなMakefileを使用します。
.SUFFIXES: .xml .out
.xml.out:
Java -jar ProcessFile.jar $< 1> $@
そしてこうして呼び出されます:
find /dump -type f -name '*.xml' | sed -e 's/\.xml$/.out/' | xargs make -j8
さらに良いことに、Javaプロセスが正常に完了した場合にのみ出力ファイルが作成されるようにすると、make
の依存関係処理を利用して、次回は未処理のファイルのみを確実に処理できます。ファイルが完了します。
検索には、「+」記号を使用して直接使用できる並列オプションがあります。 xargsは必要ありません。それをgrepと組み合わせると、一致するものを探してツリー全体をすばやく移動できます。たとえば、 'foo'という文字列を含むsourcesディレクトリ内のすべてのファイルを探している場合は、find sources -type f -exec grep -H foo {} +