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

Chr*_*urm 22 process io xargs parallelism

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

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

<start-of-line-1><line-2><end-of-line-1>
Run Code Online (Sandbox Code Playgroud)

当我在整个输出的模式中使用egrepwith 时^xargs这弄乱了我的结果。

有没有办法强制xargs按顺序写入进程输出(任何顺序,只要一个进程的输出是连续的)?

或者其他一些解决方案?

编辑:有关用例的更多详细信息:

我想从不同的主机下载和解析网页。由于每个页面都需要大约一秒钟的时间来加载,并且有几十个页面我想并行化请求。

我的命令具有以下形式:

echo -n $IPs | xargs --max-args=1 -I {} --delimiter ' ' --max-procs=0 \
wget -q -O- http://{}/somepage.html | egrep --count '^string'
Run Code Online (Sandbox Code Playgroud)

我使用 bash 而不是 Perl 之类的东西,因为主机 IP($IPs 变量)和其他一些数据来自包含的 bash 文件。

Ole*_*nge 18

GNU Parallel 是专门为解决这个问题而设计的:

echo -n $IPs | parallel -d ' ' -j0 wget -q -O- http://{}/somepage.html | egrep --count '^string'
Run Code Online (Sandbox Code Playgroud)

如果您的 IP 位于文件中,则它甚至更漂亮:

cat IPs | parallel -j0 wget -q -O- http://{}/somepage.html | egrep --count '^string'
Run Code Online (Sandbox Code Playgroud)

要了解更多信息,请观看介绍视频:http : //www.youtube.com/watch?v=OpaiGYxkSuQ

  • 不错的工具!另外,我敢打赌有人很快就会告诉你猫没用了。 (3认同)

Sté*_*nez 7

这应该可以解决问题:

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; }
Run Code Online (Sandbox Code Playgroud)

这里的想法是进行单独的计数并在最后总结这些。如果单独的计数大到足以混合,则可能会失败,但事实并非如此。