使用GNU parallel拆分命令行参数

49

使用GNU parallelhttp://www.gnu.org/software/parallel/

我有一个需要两个参数的程序,例如:

$ ./prog file1 file2
$ ./prog file2 file3
...
$ ./prog file23456 file23457
我使用一个生成文件名对的脚本,但这会带来问题,因为脚本的结果是一个单独的字符串 - 而不是一对。例如:

我使用一个生成文件名对的脚本,但这会带来问题,因为脚本的结果是一个单独的字符串 - 而不是一对。

$ ./prog "file1 file2"

GNU parallel似乎有很多技巧,我想知道是否有一个用于在分隔符周围拆分文本的技巧:

$ generate_file_pairs | parallel ./prog ?  
  # where ? is text under consideration, like "file1 file2"

简单的解决方法是在 prog 中手动分割参数,但我想知道是否可以在 GNU parallel 中实现。

4个回答

86

你可能正在寻找--colsep

generate_file_pairs | parallel --colsep ' ' ./prog {1} {2}  

阅读 man parallel 了解更多信息。如果您还没有这样做,请观看介绍视频 http://www.youtube.com/watch?v=OpaiGYxkSuQ


1
当我阅读初始问题时,它看起来像“generate_file_pairs”将输出带引号的内容。 --colsep 不会删除引号,对吗?假设引号围绕文本,有没有办法用 parallel 去掉它们?例如,以下代码无法正常工作:echo '"file1 file2"' | parallel --colsep ' ' ./prog {1} {2} - Steve Koch
从版本20140722开始:echo '"file1 file2"' | parallel --colsep ' ' echo '{=1 s/^"//=}-{=2 s/"$//=}' - Ole Tange
@OleTange有没有讨论或文档谈论默认分隔符行为? - Brandon Bradley
默认分隔符是 \n。它仅在换行符上进行分隔,不会在其他任何地方进行分隔。 - Ole Tange

3

虽然来晚了,但我经常遇到这个问题,并找到了一个不错的简单解决方案

在将参数列表传递给并行处理之前,只需用换行符替换所有空格。 我发现tr是这种操作中最快的工具

无效的

echo "1 2 3 4 5"  | parallel echo --
-- 1 2 3 4 5

工作中

echo "1 2 3 4 5" | tr ' ' '\n' | parallel echo --
-- 1
-- 2
-- 3
-- 4
-- 5

小贴士:在实际运行并行命令之前,我会做两件事来检查参数是否已正确分割。

  1. 在bash命令前添加echo。这意味着将要执行的任何命令都将被打印出来供您先检查。
  2. 在echo中添加一个标记,以检查并行拆分是否实际起作用

> 注意,这最适用于小/中型参数列表。如果参数列表非常大,则最好只使用for循环来回显每个参数到并行。


1
非常感谢超过2年后的帮助!!在xargs中,我可以使用"-n1"来将每个空格分隔为新行,"-nX"表示每隔X个空格分隔一次。但是出于某种原因,parallel在这方面无法起作用。所有的答案都无法帮助我将"hi there"分开到不同的行,而这个解决方案要比查看手册并编写一个大20倍的命令来得好得多,而且下次更新bash或parallel时也不会出问题。 - eyeseaevan

2
您正在寻找parallel的-n选项。以下是您需要的内容:
./generate_file_pairs | parallel -n 2 ./prog {}

来自GNU Parallel Doc的摘录:

-n max-args
    Use at most max-args arguments per command line. Fewer than max-args 
    arguments will be used if the size (see the -s option) is exceeded, 
    unless the -x option is given, in which case GNU parallel will exit.

这不会进行分割。例如:echo hi there | parallel -n 2 echo {2} x {1} => x hi there(在这种情况下没有{2})。使用--colsep:echo hi there | parallel -n 2 --colsep ' ' echo {2} x {1} ==> there x hi - Joshua Goldberg

1
在Parallel的手册中,它说道:
如果没有给出命令,则执行输入行... GNU Parallel通常可以用作xargs或cat | bash的替代品。
所以尝试一下:
generate command | parallel

试着理解以下代码的输出:

for i in {1..5};do echo "echo $i";done | parallel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接