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

Is there a way to force xargs to send multiple lines at once?

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

有办法吗?我对 -L-n 的各种组合都没有任何运气。不幸的是,我想我也坚持使用 -I 来参数化输入,因为如果我不使用 -I.

我的命令似乎不想采用标准输入

基本思想是我正在尝试使用 xargs 模拟小批量处理。

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

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

上面的

^,process_line很容易改成一次处理多行,现在这个功能是瓶颈。为了强调,上面 -n 10-L 10 似乎没有做任何事情,我的线路仍然一次处理一个。

每个 Shell 调用多行

这里不要使用-I。它可以防止一次传递多个参数,并且当用于将值替换为作为代码传递的字符串时,它是彻头彻尾的主要安全错误危险。

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

在这里,我们从代码中带外传递由 xargs 添加的参数,位于从 </code> 及以后填充的位置,然后使用 <code>"$@" 进行迭代在他们之上。

请注意,这减少了开销,因为它将多个参数传递给每个 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 shells。根据口味调整您的论点:-n 值越高,启动新 shell 的时间就越少,但最后的浪费量会增加(如果一个过程还有 8 个要进行,而其他所有过程都已完成,您的操作不是最理想的)。