使用GNU Parallel运行bash脚本

9

我有一个脚本,使用while read逐行处理某个文件。

当我执行以下命令时:

head -n5 file1 | ./myscript.sh

我能很好地得到我的结果。

但是,尝试使用gnu parallel 进行并行化:

head -n5 file1 | parallel -j 4 ./myscript.sh

产生的 result 文件为空!?

我也尝试了以下操作:

parallel -j 4 -a file1 ./myscript.sh

但仍然不起作用。我尝试按照文档中所说的做法,但没有任何成功。

编辑:

也许这可以帮助:

head -n5 file1 | parallel -a - -j 4 echo #this works
head -n5 file1 | parallel -a - -j 4 ./myscript #this doesn't
2个回答

8

parallel不会将输入的行发送到给定命令的stdin,而是将该行追加到所给命令的末尾。

如果像您所写的那样执行,则实际上相当于调用./myscript.sh <INPUT>,而您想要调用./myscript.sh并将输入作为stdin发送。

以下代码应该可以解决问题:

head -n5 file1 | parallel -j 4 "echo {} | ./myscript.sh"

{} 表示你想让输入进入 parallel 的位置,而不是默认的结尾。


1
如果这个脚本正在写入结果文件,那么它可能会每次都覆盖它。你需要让它追加到文件中。parallel会为输入行创建一个新的脚本实例。 - gandaliter
你关于append的想法是正确的,但现在我的文件计数器在每行增加时都停留在1,因为所有这些进程都是隔离的。无论如何,你能解释一下我上面的编辑情况吗? - branquito
1
我不知道你指的计数器是什么;这个脚本做什么?echo <SOMETHING> 输出 <SOMETHING>,所以你的第一个例子应该将每一行打印到 stdout。但是你的脚本需要从 stdin 接收输入,而不是作为参数传递。 - gandaliter
现在并行工作正常了,但我得到了重复和错误的结果,因为在我的脚本中,我正在使用grep从一个文件中匹配单词到另一个大文件上,它不应该负责将文件分成每个进程的块,以便它们不会混合吗? - branquito
1
每个脚本实例只会被给予一行输入。我不是很明白你想用这个脚本做什么。你能把它发出来吗? - gandaliter
让我们在聊天中继续这个讨论。 - branquito

5

--管道是为您量身定制的:

cat file1 | parallel --pipe -N5 ./myscript.sh

但是你需要更改myscript.sh,使其不保存到result而是将输出打印到stdout。然后你可以:

cat file1 | parallel --pipe -N5 ./myscript.sh > result

并且避免任何混淆。


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