我需要多次运行可执行文件,每次都使用两个命令行参数。我曾经用于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 个参数。然后将每个数字解释为一个参数,因此每一行都解释为两个参数。run
xargs
args.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
工具将所有空白组转换为换行符。