2017-08-23 136 views
2

我已经看到关于此主题的几个问题,但我缺乏将此转换为我的特定问题的能力。我有一个for循环通过子目录循环,然后在每个目录内的压缩文本文件上执行.sh脚本。我想并行化这个过程,但我很努力应用gnu并行。gnu并行并行for循环

这里是我的循环:

for d in ./*/ ; do (cd "$d" && script.sh); done 

我明白我需要输入列表转换成并行的,所以我一直在尝试这样的:

ls -d */ | parallel cd && script.sh 

虽然这似乎上手,我得到错误时的gzip试图解压目录内的txt文件中的一个,说文件不存在:

gzip: *.txt.gz: No such file or directory 

但是,当我运行原始循环时,除了需要花费一个世纪才能完成之外,我没有任何问题。另外,在使用parallel时,我只能得到gzip错误,考虑到我有超过1000个子目录,这太奇怪了。

我的问题是:

  1. 我如何并行的情况下,我的工作?如何并行化将.sh脚本的应用程序并行化到其自己的子目录中的1000个文件?即 - 我的问题的解决方案是什么?我必须取得进展。

  2. 我错过了什么?语法,循环,坏脚本?我想学习。

  3. 并行实际上是否试图并行运行所有这些.sh脚本?为什么我不知道每个.txt.gz文件都有错误?

  4. 是平行的应用程序的最佳选择?有没有更适合我需求的选择?

回答

4

两个问题:

  1. 在:

    ls -d */ | parallel cd && script.sh 
    

    什么是平行只是cd,不script.shscript.sh只执行一次,毕竟parallel cd作业已经运行,如果没有错误。这是一样的:

    ls -d */ | parallel cd 
    if [ $? -eq 0 ]; then script.sh; fi 
    
  2. 你没有目标目录传递给cd。那么,parallel执行什么只是cd,它只是将当前目录更改为您的主目录。最后的script.sh在当前目录(从您调用该命令的位置)执行,其中可能没有*.txt.gz文件,因此出现该错误。

您可以检查自己的第一个问题与效果:

$ mkdir /tmp/foobar && cd /tmp/foobar && mkdir a b c 
$ ls -d */ | parallel cd && pwd 
/tmp/foobar 

pwd输出打印一次,即使你有一个以上的输入目录。您可以通过引用命令修复它,然后用检查第二个问题:

$ ls -d */ | parallel 'cd && pwd' 
/homes/myself 
/homes/myself 
/homes/myself 

您应该看到尽可能多的pwd输出,有输入目录,但它始终是相同的输出:你的home目录。您可以通过使用替换为当前输入的{}替换字符串来修复第二个问题。检查它:

$ ls -d */ | parallel 'cd {} && pwd' 
/tmp/foobar/a 
/tmp/foobar/b 
/tmp/foobar/c 

现在,你应该有所有输入目录正确列在输出。

为了您的具体问题,这应该工作:

ls -d */ | parallel 'cd {} && script.sh' 
+0

奈斯利解释! –