2012-01-20 3 views
3

設定:のbash:チャンク内のファイルのプロセスリスト

、私はいくつかのコマンドcmdを使用して処理する必要があるいくつかの百input0.datinput1.datのようなものをという名前のファイル、...、input150.datを、持っている(これは基本的にすべてのファイルの内容をマージします)。 cmdは、最初のオプションとして、出力ファイル名と、すべての入力ファイル名のリストを取ります

./cmd output.dat input1.dat input2.dat [...] input150.dat 

問題:

問題は、スクリプトのみに起因して10個のファイルまたはそのように扱うことができるということですメモリの問題(それを私に責めないでください)。したがって、代わりに

./cmd output.dat *dat 

ようbashワイルドカード拡張機能を使用して、私はその後、私は一時的な出力をマージすることができ

./cmd temp_output0.dat file0.dat file1.dat [...] file9.dat 
[...] 
./cmd temp_outputN.dat fileN0.dat fileN1.dat [...] fileN9.dat 

ような何かをする必要があります。

./cmd output.dat output0.dat [...] outputN.dat 

方法bashに、この効率的にIスクリプトを実行しますか?

私は、成功しなかった。

EDIT:cmdを呼び出すときに、出力ファイル名を最初のコマンドライン引数として指定する必要があることに注意してください。

答えて

3

i=0 
opfiles= 
mkfifo /tmp/foo 
echo *dat | xargs -n 3 >/tmp/foo& 
while read threefiles; do 
    ./cmd tmp_output$i.dat $threefiles 
    opfiles="$opfiles tmp_output$i.dat" 
    ((i++)) 
done </tmp/foo 
rm -f /tmp/foo 
wait 
./cmd output.dat $opfiles 
rm $opfiles 

あなたはi変数の値を保つだけでなく、ファイルの最後の連結セットのためにするFIFOを使用する必要があります。

したい場合は、あなたが背景./cmdの内部呼び出しをすることができますが、CMDの最後の呼び出しの前にwaitを置く:

i=0 
opfiles= 
mkfifo /tmp/foo 
echo *dat | xargs -n 3 >/tmp/foo& 
while read threefiles; do 
    ./cmd tmp_output$i.dat $threefiles& 
    opfiles="$opfiles tmp_output$i.dat" 
    ((i++)) 
done </tmp/foo 
rm -f /tmp/foo 
wait 
./cmd output.dat $opfiles 
rm $opfiles 

を更新 あなたが完全にFIFOを使用しないようにしたい場合は、することができますそれをエミュレートするために使用するプロセス置換、ように最初の書き換え:再びしばらくに配管を回避するが、kにリダイレクトから読み出し

i=0 
opfiles=() 
while read threefiles; do 
    ./cmd tmp_output$i.dat $threefiles 
    opfiles+=("tmp_output$i.dat") 
    ((i++)) 
done < <(echo *dat | xargs -n 3) 
./cmd output.dat "${opfiles[@]}" 
rm "${opfiles[@]}" 

whileループの後に変数opfilesを入れてください。

+0

はい!それが私が探していたものです。ありがとう。 – fuenfundachtzig

+0

これは本当に必要なものよりも複雑です。一時ファイルは避けることができます。 'xargs'を' while read 'にパイプするだけです。バックグラウンド処理は素晴らしいかもしれませんが、仕事がどれほど重いかなどによって不必要に複雑になることもあります。 – tripleee

2

次のことを試してみてください、それはあなたのために働くべきでは:

echo *dat | xargs -n3 ./cmd output.dat 

はEDIT:あなたのコメントへの返信

./cmdに一度に3つ以下のファイルを送信します
for i in {0..9}; do 
    echo file${i}*.dat | xargs -n3 ./cmd output${i}.dat 
done 

file00.datからfile99.datまでのすべてのファイルを上書きし、10個の異なる出力ファイルを持つoutput1.datoutput9.datを持ちます。

あなたが行うことができます
+0

私はあなたのために働くと思うものを追加しました。それはあなたが意味することですか? – spatz

+0

いいえ、実際には、入力ファイルごとに同じ出力名を複数回使用しているため、実際には正しく機能しません。 – fuenfundachtzig