xargs 和 GNU 并行之间的区别

xargs 和 GNU 并行之间的区别

我需要多次运行可执行文件,每次都使用两个命令行参数。我曾经用于xargs此目的,但最近我意识到 GNU 的存在parallel,原则上它似乎是一个更好的工具(更多功能,更最新,更广泛的文档等) 。

另外,对我来说一个强有力的卖点是声称它可以用作“替代品xargs”(https://www.gnu.org/software/parallel/history.html)。然而,我在最后一点上遇到了一些麻烦。

假设我有一个文本文件,args.txt有几行,其中每行包含两个用空格分隔的数字,例如:

1 2
7 9
11 13

我想run为每一行运行一次我的程序(即为每对参数运行一次)。与xargs我会做

cat args.txt | xargs -n2 run

其中-n2表示每次调用xargs时应传递 2 个参数。然后将每个数字解释为一个参数,因此每一行都解释为两个参数。runxargsargs.txt

然而,当我尝试使用作为上述情况的parallel直接替代品时,我得到了不同的行为。xargs

为了说明这一点,我将使用以下小 python 脚本来代替我的程序运行:

打印机.py:

import sys
print([x for x in sys.argv[1:]])

现在,使用 xargs 我得到:

> cat args.txt | xargs -n2 python printer.py

['1', '2']
['7', '9']
['11', '13']

parallel我得到

> cat args.txt | parallel -n2 python printer.py

['1 2', '7 9']
['11 13']

因此,当xargs使用单独的(空格分隔的)数字作为参数调用 python 脚本时,parallel会将每一行解释为单个参数,这意味着例如在第一次调用时,第一个参数"1 2"不仅仅是"1"

我对此有点困惑,因为我本来期望parallel作为 的直接替代品xargs,但显然它比这更微妙。我想我的问题是我应该如何使用parallel来实现与我正在做的相同的事情xargs,但我也很好奇为什么这里的行为存在差异,以及是否是故意的。

答案1

xargs您遇到了和之间为数不多的不兼容性之一,parallel这是设计使然。

GNU Parallel 将确保输入被引用为单个参数,而 xargs 则不会。它是编写 GNU Parallel 第一个版本的原始驱动力之一。

$ echo '9" nails in 10" boxes' | xargs echo
9 nails in 10 boxes
$ echo '9" nails in 10" boxes' | parallel echo
9" nails in 10" boxes

但是,您可以强制 GNU Parallel 不引用输入:

cat args.txt | parallel python printer.py {=uq=}

这将从命令中取出一行args.txt并将其插入到命令中,而不用引用它。

(版本 20190722 或更高版本)。

另一种选择是将列拆分为单个空格(如评论中所述):

cat args.txt | parallel --colsep ' ' python printer.py

或者空白:

cat args.txt | parallel --colsep '\s+' python printer.py

(版本 20100822 或更高版本)。

答案2

并行一次读取一行输入,与读取单词的 xargs 不同。

您可以像这样获得相同的结果:

> sed 's/\s\+/\n/g' args.txt | parallel -n2 python printer.py

在这里,该sed工具将所有空白组转换为换行符。

相关内容