私はxargs
をオプション--max-args=0
とともに使用しています(または-P 0
)。
ただし、プロセスの出力は、適切な行分離を考慮せずにstdout
ストリームにマージされます。だから私はしばしば次のような行になるでしょう:
<start-of-line-1><line-2><end-of-line-1>
egrep
を使用してパターン全体で^
をxargs
で使用しているため、これは結果を台無しにしています。
xargs
にプロセス出力を順番に(1つのプロセスの出力が連続している限り、任意の順序で)強制的に書き込む方法はありますか?
または他の解決策はありますか?
編集:ユースケースの詳細:
さまざまなホストからWebページをダウンロードして解析したい。すべてのページの読み込みに約1秒かかり、リクエストを並列化したいページが数ダースあるので。
私のコマンドの形式は次のとおりです。
echo -n $IPs | xargs --max-args=1 -I {} --delimiter ' ' --max-procs=0 \
wget -q -O- http://{}/somepage.html | egrep --count '^string'
ホストIP($ IPs変数)とその他のデータは含まれているbashファイルから取得されるため、Perlのようなものではなくbashを使用しています。
これでうまくいくはずです:
echo -n $IPs | xargs --max-args=1 -I {} --delimiter ' ' --max-procs=0 \
sh -c "wget -q -O- 'http://{}/somepage.html' | egrep --count '^string'" | \
{ NUM=0; while read i; do NUM=$(($NUM + $i)); done; echo $NUM; }
ここでの考え方は、個別にカウントし、最後にこれらを合計することです。個別のカウントが混合されるほど大きい場合は失敗する可能性がありますが、そうではありません。
GNU Parallelは、この問題を解決するために特別に設計されています。
echo -n $IPs | parallel -d ' ' -j0 wget -q -O- http://{}/somepage.html | egrep --count '^string'
IPがファイル内にある場合は、さらにきれいです。
cat IPs | parallel -j0 wget -q -O- http://{}/somepage.html | egrep --count '^string'
詳細については、紹介ビデオをご覧ください: http://www.youtube.com/watch?v=OpaiGYxkSuQ