我正在使用xargs
该选项--max-args=0
(或者-P 0
)。
然而,进程的输出被合并到stdout
流中,而不考虑适当的行分离。所以我经常会得到这样的行:
<start-of-line-1><line-2><end-of-line-1>
当我在整个输出的模式中使用egrep
with时,这弄乱了我的结果。^
xargs
是否有某种方法强制xargs
按顺序写入进程输出(任何顺序,只要一个进程的输出是连续的)?
或者其他解决方案?
编辑:有关用例的更多详细信息:
我想从不同的主机下载并解析网页。由于每个页面加载大约需要一秒钟,并且有几十个页面,我想并行化请求。
我的命令具有以下形式:
echo -n $IPs | xargs --max-args=1 -I {} --delimiter ' ' --max-procs=0 \
wget -q -O- http://{}/somepage.html | egrep --count '^string'
我使用 bash 而不是 Perl 之类的东西,因为主机 IP($IPs 变量)和其他一些数据来自包含的 bash 文件。
答案1
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
答案2
这应该可以解决问题:
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; }
这里的想法是进行单独的计数并在最后将它们相加。如果单独的计数大到足以混合,则可能会失败,但情况不应该如此。