次の形式のbashスクリプトを作成しました。
#!/bin/bash
start=$(date +%s)
inFile="input.txt"
outFile="output.csv"
rm -f $inFile $outFile
while read line
do
-- Block of Commands
done < "$inFile"
end=$(date +%s)
runtime=$((end-start))
echo "Program has finished execution in $runtime seconds."
while
ループは$inFile
から読み取り、行で何らかのアクティビティを実行し、結果を$outFile
にダンプします。
$inFile
は3500行以上あるため、スクリプトを完全に実行するには6〜7時間かかります。この時間を最小限に抑えるために、このスクリプトではマルチスレッドまたはフォークを使用することを計画しています。 8つの子プロセスを作成すると、$inFile
の8行が同時に処理されます。
これはどのように行うことができますか?
GNU parallel
は、この種のもののために作られています。スクリプトは一度に何回でも実行でき、入力ごとに異なるデータがパイプラインされます。
cat input.txt | parallel --pipe your-script.sh
デフォルトでは、システムのプロセッサ数に応じてプロセスを生成しますが、-j N
でカスタマイズできます。
特に巧妙なトリックは、シバンラッピング機能です。 Bashスクリプトの最初の行を次のように変更した場合:
#!/usr/bin/parallel --Shebang-wrap --pipe /bin/bash
標準入力でデータをフィードすると、すべて自動的に行われます。最後に実行する必要があるクリーンアップコードがある場合、これはあまり役に立ちません。
注意すべきことがいくつかあります。 1つは、入力を連続したチャンクに分割し、一度に1つずつ使用することです。ラインをインターリーブしません。もう1つは、レコードの数に関係なく、それらのチャンクがサイズで分割されることです。 --block N
を使用して、異なるブロックサイズをバイト単位で設定できます。あなたの場合、ファイルサイズの8分の1以下がほぼ適切です。それ以外の場合は、ファイルが1つのブロックにすべて含まれるほど小さい可能性があり、目的を達成できない可能性があります。
特定の異なるユースケースには多くのオプションがありますが、 チュートリアル はかなりうまくカバーしています。興味のあるオプションには、--round-robin
と--group
があります。