いくつかのデータを約5または6の異なるプログラムを介してパイプ処理し、最終結果をタブ区切りファイルにパイプするbashシェルスクリプトがあります。
次に、別の同様のデータセットに対してもう一度同じことを行い、2番目のファイルに出力します。
次に、両方のファイルを別のプログラムに入力して、比較分析を行います。例えば単純化する
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv
AnalysisProg -i Data1res.csv Data2res.csv
私の質問は:ステップ1とステップ2を同時に(たとえば、&を使用して)実行するにはどうすればよいですか?
どうも
ps AnalysisProgは、ストリームまたはfifoでは機能しません。
wait
を使用します。例えば:
Data1 ... > Data1Res.csv &
Data2 ... > Data2Res.csv &
wait
AnalysisProg
意志:
たとえば、 この質問 を参照してください。
ファイルが2つしかない場合、cxwの答えは間違いなく望ましい解決策です。 2つのファイルが単なる例であり、実際には10000個のファイルがある場合、「&」ソリューションは機能しません。サーバーが過負荷になるためです。そのためにはGNU Parallel:
ls Data* | parallel 'cat {} | this | that |theother | grep |sed | awk |whatever > {}res.csv
AnalysisProg -i *res.csv
GNU Parallelの詳細:
これを行う1つの方法は次のようになります。
AnalysisProg <<PREPROCESS /dev/stdin
$(
{ process1=$( pipe | line | 1 >&2 & echo $! )
process2=$( pipe | line | 2 >&2 & echo $! )
while ps -p $process1 $process2 >/dev/null; do
sleep 1
done
} 2>&1
)
#END
PREPROCESS
このようにして、両方のパイプラインのバックグラウンドを設定し、実行が完了するまで待ってから、それらの出力を結合してstdinにします。これは、ヒアドキュメントで評価され、AnalysisProgに渡されます。 wait
を使用できる場合、これはwhile ps
ループよりも優れていますが、シェル依存しているwait
は、が現在のシェルの子ではないプロセスで待機するように指示した場合、反対することができます。
また、上記の方法では出力が照合されるため、両方のプロセスが同時に書き込みを行うことに注意してください。代わりにそれらを分離したい場合、または別のものに追加したい場合は、次のようにすることができます:
AnalysisProg 3<<PREPROCESS /dev/fd/3 /dev/stderr
$(
process1=$(... >&2 ...) 2>/dev/fd/3
...
} 3>/dev/fd/3 2>/dev/stderr
)
これを使ってみてください。
rm -f Data1Res.csv
rm -f Data2Res.csv
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv &
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv &
while true
do
ps aux | grep -v grep | grep -i -E 'Data1Res.csv|Data2Res.csv' &> /dev/null
if [ $? -ne 0 ]
then
AnalysisProg -i Data1res.csv Data2res.csv
exit 0
fi
done