gnu parallel 并行化一个for循环
gnu parallel to parallelize a for loop
我已经看到几个关于这个主题的问题,但我无法将其转化为我的具体问题。我有一个 for 循环,循环遍历子目录,然后在每个目录内的压缩文本文件上执行 .sh 脚本。我想并行化这个过程,但我正在努力应用 gnu parallel。
这是我的循环:
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
然而,当我 运行 原始的 for 循环时,除了需要一个世纪才能完成之外,我没有任何问题。此外,我在使用并行时只遇到一次 gzip 错误,考虑到我有超过 1000 个子目录,这太奇怪了。
我的问题是:
如何让 Parallel 在我的案例中工作?如何并行化将 .sh 脚本的应用程序并行化到它们自己的子目录中的 1000 个文件?即-我的问题的解决方案是什么?我要进步。
我错过了什么?语法、循环、糟糕的脚本?我想学
Parallel 实际上是在尝试 运行 所有这些 .sh 脚本并行吗?为什么我没有收到每个 .txt.gz 文件的错误?
并行是应用程序的最佳选择吗?还有其他更适合我需求的选择吗?
两个问题:
在:
ls -d */ | parallel cd && script.sh
并行的只是cd
,而不是script.sh
。 script.sh
只执行一次,毕竟parallel cd
个作业有运行,如果没有报错的话。等同于:
ls -d */ | parallel cd
if [ $? -eq 0 ]; then script.sh; fi
您没有将目标目录传递给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
输出,但它始终是相同的输出:您的主目录。您可以使用替换为当前输入的 {}
替换字符串来解决第二个问题。检查它:
$ ls -d */ | parallel 'cd {} && pwd'
/tmp/foobar/a
/tmp/foobar/b
/tmp/foobar/c
现在,您应该在输出中正确列出了所有输入目录。
对于您的具体问题,这应该有效:
ls -d */ | parallel 'cd {} && script.sh'
我已经看到几个关于这个主题的问题,但我无法将其转化为我的具体问题。我有一个 for 循环,循环遍历子目录,然后在每个目录内的压缩文本文件上执行 .sh 脚本。我想并行化这个过程,但我正在努力应用 gnu parallel。
这是我的循环:
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
然而,当我 运行 原始的 for 循环时,除了需要一个世纪才能完成之外,我没有任何问题。此外,我在使用并行时只遇到一次 gzip 错误,考虑到我有超过 1000 个子目录,这太奇怪了。
我的问题是:
如何让 Parallel 在我的案例中工作?如何并行化将 .sh 脚本的应用程序并行化到它们自己的子目录中的 1000 个文件?即-我的问题的解决方案是什么?我要进步。
我错过了什么?语法、循环、糟糕的脚本?我想学
Parallel 实际上是在尝试 运行 所有这些 .sh 脚本并行吗?为什么我没有收到每个 .txt.gz 文件的错误?
并行是应用程序的最佳选择吗?还有其他更适合我需求的选择吗?
两个问题:
在:
ls -d */ | parallel cd && script.sh
并行的只是
cd
,而不是script.sh
。script.sh
只执行一次,毕竟parallel cd
个作业有运行,如果没有报错的话。等同于:ls -d */ | parallel cd if [ $? -eq 0 ]; then script.sh; fi
您没有将目标目录传递给
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
输出,但它始终是相同的输出:您的主目录。您可以使用替换为当前输入的 {}
替换字符串来解决第二个问题。检查它:
$ ls -d */ | parallel 'cd {} && pwd'
/tmp/foobar/a
/tmp/foobar/b
/tmp/foobar/c
现在,您应该在输出中正确列出了所有输入目录。
对于您的具体问题,这应该有效:
ls -d */ | parallel 'cd {} && script.sh'