Option Description
-j n 并行运行 n 个工作
-k 保持同一顺序
-X 用上下文替换多个参数
--colsep regexp 根据 regexp 分割输入,进行位置替换
{} {.} {/} {/.} {#} 替换字符串
{3} {3.} {3/} {3/.} 位置替换字符串
-S sshlogin 例如:foo@server.example.com
--trc {}.bar --transfer --return {}.bar --cleanup 的缩写
--onall 在所有 sshlogins 上运行带有参数的给定命令
--nonall 在所有 sshlogins 上运行不带参数的给定命令
--pipe 将 stdin(标准输入)拆分为多个工作。
--recend str 记录--管道的末端分隔符。
--recstart str 记录--管道的起始分隔符。

GNU Linux 中的作业可以使用 GNU parallel 进行并行处理。一个作业可以是一条命令,也可以是一个小脚本,必须针对输入中的每一行运行。典型的输入是文件列表、主机列表、用户列表、URL 列表或表格列表。作业也可以是从管道中读取的命令。

Section 63.1: 并行处理文件列表中的重复任务

如果能利用更多的计算机资源(如 CPU 和 RAM),许多重复性工作就能更高效地完成。下面是并行运行多个工作的示例。

假设有一个 < 文件列表 >,例如从 ls 输出的文件。另外,假设这些文件是 bz2 压缩文件,需要按以下顺序对它们执行任务。

  1. 使用 bzcat 将 bz2 文件解压到 stdout
  2. 使用 grep <some key word> 命令grep(例如过滤)包含特定关键词的行
  3. 使用 gzip 将输出管道连接到一个压缩文件中

使用 while 循环运行时可能如下所示

filenames="file_list.txt"
while read -r line
do
    name="$line"
    ## grab lines with puppies in them
    bzcat $line | grep puppies | gzip >> output.gz
done < "$filenames"

使用 GNU Parallel,我们可以同时运行 3 个并行作业,只需执行

parallel -j 3 "bzcat {} | grep puppies" ::: $( cat filelist.txt ) | gzip > output.gz

该命令简单明了,在文件数量和文件大小较大时更有效。工作由 parallel 启动,选项 -j 3 启动 3 个并行工作,并行工作的输入由 :::. 接收,输出最终被管道输送到 gzip > output.gz 中。

Section 63.2: 并行处理 STDIN

现在,假设我们有一个大文件(例如 30 GB)需要逐行转换。假设我们有一个脚本 convert.sh,可以完成这个 <task>。我们可以把这个文件的内容导入 stdin,让并行程序分块接收和处理,例如

<stdin> | parallel --pipe --block <block size> -k <task> > output.txt

其中,“<stdin>”可以来自任何东西,如 “cat <file>”。

作为一个可重复的例子,我们的任务是 nl -n rz。取任何文件(我的文件是 data.bz2)并将其传递给 <stdin>

bzcat data.bz2 | nl | parallel --pipe --block 10M -k nl -n rz | gzip > ouptput.gz

上面的示例从 bzcat data.bz2 | nl 中获取了 <stdin>,我加入 nl 只是为了证明最终的 output output.gz 将按照接收到的顺序保存。然后,parallel 将 <stdin> 分成大小为 10 MB 的块,并将每个块通过 nl -n rz,在这里它只是添加了一个正确对齐的数字(更多细节请参阅 nl --help )。选项 --pipe告诉并行程序将 <stdin> 分割成多个任务,--block指定块的大小。选项 -k 指定必须保持排序。

您的最终输出结果应如下所示

000001 1 <data>
000002 2 <data>
000003 3 <data>
000004 4 <data>
000005 5 <data>
...
000587 552409 <data>
000588 552410 <data>
000589 552411 <data>
000590 552412 <data>
000591 552413 <data>

我的原始文件有 552 413 行。第一列代表并行作业,第二列代表分块传递给并行作业的原始行号。你应该注意到,第二列(以及文件的其他部分)的顺序保持不变。