有没有办法强制xargs一次发送多行?

时间:2017-10-09 23:22:38

标签: bash concurrency batch-processing xargs

我有一份工作从一个\ n分隔的流中读取数据,并将信息一次发送到xargs以处理1行。问题是,这不够高效,但我知道如果我改变程序使得xargs执行的命令一次发送多行而不是一行,它可以大大提高我的脚本的性能。 / p>

有办法做到这一点吗?我对-L-n的各种组合没有任何好运。不幸的是,我认为我还坚持使用-I来参数化输入,因为如果我不使用-I,我的命令似乎不想接受标准输入。<\ n / p>

我的基本想法是尝试使用xargs模拟小批量处理。

从概念上讲,这里的内容类似于我目前所写的内容

contiguous-stream | xargs -d '\n' -n 10 -L 10 -I {} bash -c 'process_line {}'

^在上面,process_line很容易改变,因此它可以同时处理多行,而这个功能现在是瓶颈。对于上面的重点,-n 10-L 10似乎没有做任何事情,我的线路仍在处理一个。

1 个答案:

答案 0 :(得分:7)

每个Shell调用多行

请勿在此处使用-I。它可以防止一次传递多个参数,并且当用于将值替换为作为代码传递的字符串时,它是彻头彻尾的主要安全漏洞。

contiguous-stream | xargs -d $'\n' -n 10 \
  bash -c 'for line in "$@"; do process_line "$line"; done' _

在这里,我们将xargs带外的参数从代码传递到$1及以后填充的位置,然后使用"$@"迭代它们

请注意,这样可以减少开销,因为它会向每个shell传递多个参数(因此您需要花费较少的时间来支付shell启动成本),但并不实际并发处理所有这些参数。为此,你想......

多条并行线

假设GNU xargs,您可以使用-P指定并行处理级别:

contiguous-stream | xargs -d $'\n' -n 10 -P 8 \
  bash -c 'for line in "$@"; do process_line "$line"; done' _

在这里,我们将10个参数传递给每个shell,并一次运行8个shell 。调整您的品味参数:-n更高的值花费更少的时间来启动新的shell,但最后会增加浪费(如果一个进程仍有8个进程而其他每个进程都已完成,那么您正在运行未达最佳)。