GNU Parallel - 这些嵌套的并行可以是单个并行调用吗?

时间:2016-02-17 15:35:14

标签: bash gnu-parallel

我有一个文件夹,每隔5分钟就有一个文件。假设文件名是' Test-HHMM.png'对于每个文件,我想检查每个文件是否存在。到目前为止,我所拥有的是什么。

parallel "[ -f {1} ] || echo '{1} - Nope'" ::: $(parallel printf %s-%02d%02d.png\\\\n {1} {2} {3} ::: 'Test' ::: $(seq 0 23) ::: $(seq 0 5 55))

首先拨打parallel,使用printf创建一系列文件名,使用2次调用seq生成小时和分钟。然后第二次调用parallel对每个文件名进行-f测试。

这似乎只是对parallel的一次调用,其中命令是对-f所有参数的结果进行$(printf)测试。但我似乎无法正确使用语法。我似乎也无法将命令分解为子命令然后连接,以使事情更容易阅读。

有什么想法?使用parallel错误似乎有点冒险;感觉我最好不要使用循环。

更新 这是我的问题的精简版本 - 看起来像Addtrivial,但我可以从此构建到我需要的东西。我目前有这个:

parallel echo $(printf %02d {1}) ::: $(seq 1 10)

我希望打印出来 01 02 ... 10

相反,我得到了 ./foo.sh: line 7: printf: {1}: invalid number 00 1 00 2 ... 00 10

不知道为什么。尝试了许多组合。和"没有效果。

谢谢!

2 个答案:

答案 0 :(得分:1)

首先:你确定这不是XY problem吗?

如果您正在监视目录以查看是否制作了新文件,那么这样做会更好:

inotifywait -q -m -r -e MOVED_TO -e CLOSE_WRITE --format %w%f my_dir | parallel -u echo

但如果您真的想查看文件是否存在,那么Perl中的单个循环会更快:GNU Parallel擅长运行时间超过几毫秒的任务。

perl -e 'print map {$_."\n"} grep { ! -e $_ } map { $a=$_*5; map { sprintf "Test-%02d%02d.png", $_,$a } "00"..23 } 0..11' |
  parallel echo {} - Nope

在这里,我假设你真的想做一些比echo更严肃的事情。否则,您只需将map放在print之后。

编辑:

如果运行时间不是问题,那么这是一种相当紧凑的方法:

parallel [ -f Test-{1}{2} ] "||" echo Test-{1}{2} - Nope ::: {00..23} ::: {00..55..5}

如果您要运行的内容更复杂,请执行以下操作:

mytest() {
  file="$1"
  if [ -f "$file" ] ; then
    true
  else
    echo "$file" - Nope
  fi
}
export -f mytest
parallel mytest Test-{1}{2} ::: {00..23} ::: {00..55..5}

答案 1 :(得分:1)

参考我编辑中的简化示例...这不起作用

parallel echo $(printf %02d {1}) ::: $(seq 1 10)

...但这确实

parallel echo "\$(printf %02d {1})" ::: $(seq 1 10)

问题是我需要逃避$,因此表达式将由parallel评估,而不是bash评估。

因此,原始问题的解决方案变为

parallel "file=\$(printf %s-%02d%02d.kml {1} {2} {3}) && [ -f \$file ] || echo \$file - Nope" ::: 'Foo' ::: $(seq 0 23) ::: $(seq 0 5 55)

另外将$(printf)的结果赋给变量,所以我不必多次调用printf。当我将printf命令分配给变量时,甚至将其工作,以防我想重用它。所以我觉得我很好。

感谢您的回答&评论家伙。