如何阻止 xargs 错误地合并多个进程的输出?

如何阻止 xargs 错误地合并多个进程的输出?

我正在使用xargs该选项--max-args=0(或者-P 0)。

然而,进程的输出被合并到stdout流中,而不考虑适当的行分离。所以我经常会得到这样的行:

<start-of-line-1><line-2><end-of-line-1>

当我在整个输出的模式中使用egrepwith时,这弄乱了我的结果。^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; }

这里的想法是进行单独的计数并在最后将它们相加。如果单独的计数大到足以混合,则可能会失败,但情况不应该如此。

相关内容