GNU Parallel的具体使用
作者:zx 发布时间:2023-06-14 16:08:58
它是什么?
GNU Parallel是一个shell工具,为了在一台或多台计算机上并行的执行计算任务,一个计算任务可以是一条shell命令或者一个以每一行做为输入的脚本程序。通常的输入是文件列表、主机列表、用户列表、URL列表或者表格列表;一个计算任务也可以是一个从管道读取的一条命令。GNU Parallel会把输入分块,然后通过管道并行的执行。
如果你会使用xargs和tee命令,你会发现GNU Parallel非常易于使用,因为GNU Parallel具有与xargs一样的选项。GNU Parallel可以替代大部分的shell循环,并且用并行的方式更快的完成计算任务。
GNU Parallel保证它的输出与顺序执行计算任务时是一样的,这样就可以方便的把GNU Parallel的输出做为其它程序的输入。
对于每一行输入,GNU Parallel会把这一行做为参数来运行指定的命令。如果没有给出命令,那么这一行会被当做命令执行。多行输入会并行的运行。GNU Parallel经常被用于替代xargs或者cat | bash。
指南
本教程展示了绝大多数GNU Parallel的功能。旨在介绍GNU Parallel中的一个选项,而非讲解真实世界中使用的例子。花一个小时的时间学习本教程,你会由此爱上上命令行。
预备
为了执行本教程中的示例,你首先需要做如下准备:
parallel >= version 20130814
安装最新版:
(wget -O - pi.dk/3 || curl pi.dk/3/) | bash
这条命令同时也会安装最新版的指南
man parallel_tutorial
本教程的大部分内容同时也兼容旧版本。
abc-file
生成文件:
parallel -k echo ::: A B C > abc-file
def-file
生成文件:
parallel -k echo ::: D E F > def-file
abc0-file
生成文件:
perl -e 'printf "A\0B\0C\0"' > abc0-file
abc_-file
生成文件:
perl -e 'printf "A_B_C_"' > abc_-file
tsv_file.tsv
生成文件:
perl -e 'printf "f1\tf2\nA\tB\nC\tD\n"' > tsv-file.tsv
num30000
生成文件:
perl -e 'for(1..30000){print "$_\n"}' > num30000
num1000000
生成文件:
perl -e 'for(1..1000000){print "$_\n"}' > num1000000
num_%header
生成文件:
(echo %head1; echo %head2; perl -e 'for(1..10){print "$_\n"}') > num_%header
远程执行:ssh免密码登录$SERVER1和$SERVER2
生成文件:
SERVER1=server.example.com
SERVER2=server2.example.net
最后应该成功运行如下命令:
ssh $SERVER1 echo works
ssh $SERVER2 echo works
使用 ssh-keygen -t dsa; ssh-copy-id $SERVER1 建立环境(使用empty pass phrase)
输入源
GNU Parallel的输入源支持文件、命令行和标准输入(stdin或pipe)
单个输入源
从命令行读取输入:
parallel echo ::: A B C
输出(由于任务以并行的方式执行,顺序可能会有所不同):
A
B
C
文件做为输入源:
parallel -a abc-file echo
输出同上。
STDIN(标准输入)做为输入源:
cat abc-file | parallel echo
输出同上。
多输入源
GNU Parallel支持通过命令行指定多个输入源,它会生成所有的组合:
parallel echo ::: A B C ::: D E F
输出:
A D
A E
A F
B D
B E
B F
C D
C E
C F
多个文件做为输入源:
parallel -a abc-file -a def-file echo
输出同上。
STDIN(标准输入)可以做为输入源中的一个,使用“-”:
cat abc-file | parallel -a - -a def-file echo
输出同上。
可以使用“::::”替代 -a:
cat abc-file | parallel echo :::: - def-file
输出同上。
::: 和 :::: 可以混合使用:
parallel echo ::: A B C :::: def-file
输出同上。
适配参数
–xapply 从每一个输入源取一个参数:
parallel --xapply echo ::: A B C ::: D E F
输出:
A D
B E
C F
如果其中一个输入源的长度比较短,它的值会被重复:
parallel --xapply echo ::: A B C D E ::: F G
输出:
A F
B G
C F
D G
E F
改变参数分隔符
GNU Parallel可以指定分隔符替代 ::: 或 ::::,当这两个符号被其它命令占用的时候会特别有用:
parallel --arg-sep ,, echo ,, A B C :::: def-file
输出:
A D
A E
A F
B D
B E
B F
C D
C E
C F
改变参数分隔符:
parallel --arg-file-sep // echo ::: A B C // def-file
输出同上。
改变参数定界符
GNU Parallel默认把一行做为一个参数:使用 \n 做为参数定界符。可以使用 -d 改变:
parallel -d _ echo :::: abc_-file
输出:
A
B
C
\0 代表NULL:
parallel -d '\0' echo :::: abc0-file
输出同上。
-0 是 -d '\0' 的简写(通常用于从 find … -print0读取输入):
parallel -0 echo :::: abc0-file
输出同上。
输入源中的结束值
GNU Parallel支持指定一个值做为结束标志:
parallel -E stop echo ::: A B stop C D
输出:
A
B
跳过空行
使用 –no-run-if-empty 来跳过空行:
(echo 1; echo; echo 2) | parallel --no-run-if-empty echo
输出:
1
2
构建命令行
没有指定命令意味着参数就是命令
如果parallel之后没有给定命令,那么这些参数会被当做命令:
parallel ::: ls 'echo foo' pwd
输出:
[当前文件列表]
foo
[当前工作目录的路径]
命令可以是一个脚本文件,一个二进制可执行文件或一个bash的函数(须用 export -f 导出函数):
# Only works in Bash and only if $SHELL=.../bash
my_func() {
echo in my_func $1
}
export -f my_func
parallel my_func ::: 1 2 3
输出:
in my_func 1
in my_func 2
in my_func 3
替换字符串
5种替换字符串
GNU Parallel支持多种替换字符串。默认使用 {}:
parallel echo ::: A/B.C
输出:
A/B.C
指定 {} :
parallel echo {} ::: A/B.C
输出同上
去掉扩展名 {.}:
parallel echo {.} ::: A/B.C
输出
A/B
去掉路径 {/}:
parallel echo {/} ::: A/B.C
输出:
B.C
只保留路径 {//}:
parallel echo {//} ::: A/B.C
输出:
A
去掉路径和扩展名 {/.}:
parallel echo {/.} ::: A/B.C
输出:
B
输出任务编号:
parallel echo {#} ::: A/B.C
输出:
1
2
3
改变替换字符串
使用 -I 改变替换字符串符号 {}:
parallel -I ,, echo ,, ::: A/B.C
输出:
A/B.C
–extensionreplace替换 {.}:
parallel --extensionreplace ,, echo ,, ::: A/B.C
输出:
A/B
–basenamereplace替换 {/}:
parallel --basenamereplace ,, echo ,, ::: A/B.C
输出:
B.C
–dirnamereplace替换 {//}:
parallel --dirnamereplace ,, echo ,, ::: A/B.C
输出:
A
–basenameextensionreplace替换 {/.}:
parallel --basenameextensionreplace ,, echo ,, ::: A/B.C
输出:
B
–seqreplace替换 {#}:
parallel --seqreplace ,, echo ,, ::: A B C
输出:
1
2
3
指定位置替换字符串
如果有多个输入源时,可以通过 {编号} 指定某一个输入源的参数:
parallel echo {1} and {2} ::: A B ::: C D
输出:
A and C
A and D
B and C
B and D
可以使用 / // /. 和 .: 改变指定替换字符串:
parallel echo /={1/} //={1//} /.={1/.} .={1.} ::: A/B.C D/E.F
输出:
/=B.C //=A /.=B .=A/B
/=E.F //=D /.=E .=D/E
位置可以是负数,表示倒着数:
parallel echo 1={1} 2={2} 3={3} -1={-1} -2={-2} -3={-3} ::: A B ::: C D ::: E F
输出:
1=A 2=C 3=E -1=E -2=C -3=A
1=A 2=C 3=F -1=F -2=C -3=A
1=A 2=D 3=E -1=E -2=D -3=A
1=A 2=D 3=F -1=F -2=D -3=A
1=B 2=C 3=E -1=E -2=C -3=B
1=B 2=C 3=F -1=F -2=C -3=B
1=B 2=D 3=E -1=E -2=D -3=B
1=B 2=D 3=F -1=F -2=D -3=B
按列输入
使用 –colsep 把文件中的行切分为列,做为输入参数。下面使用TAB(\t):
1=f1 2=f2
1=A 2=B
1=C 2=D
指定参数名
使用 –header 把每一行输入中的第一个值做为参数名:
parallel --header : echo f1={f1} f2={f2} ::: f1 A B ::: f2 C D
输出:
f1=A f2=C
f1=A f2=D
f1=B f2=C
f1=B f2=D
使用 –colsep 处理使用TAB做为分隔符的文件:
parallel --header : --colsep '\t' echo f1={f1} f2={f2} :::: tsv-file.tsv
输出:
f1=A f2=B
f1=C f2=D
多参数
–xargs 让GNU Parallel支持一行多个参数(可以指定上限):
cat num30000 | parallel --xargs echo | wc -l
输出:
2
30000个参数被分为两行。
一行中的参数个数的上限通过 -s 指定。下面指定最大长度是10000,会被分为17行:
cat num30000 | parallel --xargs -s 10000 echo | wc -l
为了获得更好的并发性,GNU Parallel会在文件读取结束后再分发参数。
GNU Parallel 在读取完最后一个参数之后,才开始第二个任务,此时会把所有的参数平均分配到4个任务(如果指定了4个任务)。
第一个任务与上面使用 –xargs 的例子一样,但是第二个任务会被平均的分成4个任务,最终一共5个任务。
cat num30000 | parallel --jobs 4 -m echo | wc -l
输出:
5
10分参数分配到4个任务可以看得更清晰:
parallel --jobs 4 -m echo ::: {1..10}
输出:
1 2 3
4 5 6
7 8 9
10
替换字符串可以是单词的一部分。通过下面两个命令体会 -m 和 -X 的区别:
parallel --jobs 4 -m echo pre-{}-post ::: A B C D E F G
输出:
pre-A B-post
pre-C D-post
pre-E F-post
pre-G-post
-X与 -m 相反:
parallel --jobs 4 -X echo pre-{}-post ::: A B C D E F G
输出:
pre-A-post pre-B-post
pre-C-post pre-D-post
pre-E-post pre-F-post
pre-G-post
使用 -N 限制每行参数的个数:
parallel -N3 echo ::: A B C D E F G H
输出:
A B C
D E F
G H
-N也可以用于指定位置替换字符串:
parallel -N3 echo 1={1} 2={2} 3={3} ::: A B C D E F G H
输出:
1=A 2=B 3=C
1=D 2=E 3=F
1=G 2=H 3=
-N0 只读取一个参数,但不附加:
parallel -N0 echo foo ::: 1 2 3
输出:
foo
foo
foo
引用
如果命令行中包含特殊字符,就需要使用引号保护起来。
perl脚本 'print “@ARGV\n”' 与linux的 echo 的功能一样。
perl -e 'print "@ARGV\n"' A
输出:
A
使用GNU Parallel运行这条命令的时候,perl命令需要用引号包起来:
parallel perl -e 'print "@ARGV\n"' ::: This wont work
输出:
[Nothing]
使用 -q 保护perl命令:
parallel -q perl -e 'print "@ARGV\n"' ::: This works
输出:
This
works
也可以使用 ' :
parallel perl -e \''print "@ARGV\n"'\' ::: This works, too
输出:
This
works,
too
使用 -quote:
parallel --shellquote
parallel: Warning: Input is read from the terminal. Only experts do this on purpose. Press CTRL-D to exit.
perl -e 'print "@ARGV\n"'
[CTRL-D]
输出:
perl\ -e\ \'print\ \"@ARGV\\n\"\'
也可以使用命令:
parallel perl\ -e\ \'print\ \"@ARGV\\n\"\' ::: This also works
输出:
This
also
works
去除空格
使用 –trim 去除参数两头的空格:
parallel --trim r echo pre-{}-post ::: ' A '
输出:
pre- A-post
删除左边的空格:
parallel --trim l echo pre-{}-post ::: ' A '
输出:
pre-A -post
删除两边的空格:
parallel --trim lr echo pre-{}-post ::: ' A '
输出:
pre-A-post
控制输出
以参数做为输出前缀:
parallel --tag echo foo-{} ::: A B C
输出:
A foo-A
B foo-B
C foo-C
修改输出前缀 –tagstring:
parallel --tagstring {}-bar echo foo-{} ::: A B C
输出:
A-bar foo-A
来源:http://www.voidcn.com/article/p-cypqjqgc-bda.html


猜你喜欢
- 国内Internet的连接速度不尽如人意已是不争的事实,于是许多网友软硬兼施,以求最大限度地提高上网速度。一时间快猫加鞭、NetAnts等网
- 问题描述:新手 想安装VMware tools与 主机进行文件共享虚拟机(M) –> 安装VMware Tools
- Linux 下对于目录的切换,大家肯定会想到一个命令:cd 命令。这个是 Linux 下再基本不过的命令,如果这个命令都不知道的话,赶紧剖腹
- 现在国内互联网形式越来越严峻,加上百度已经成为中国互联网的流量分发者,放几十年的香港就是道上的“水龙头”,大小站长都要看他脸色行事,否则便没
- 为了更好的实现用户在社区论坛的互动功能,官方开发团队在Discuz! 7.1版本引入了漫游应用插件机制,丰富了社区论坛系统互动应用效果。伴随
- 新做了一个资料类的网站,因为女朋友从事的职业的关系,老是让我给她找资料,也发现了很多资料网站的问题,这里谈一下自己对资料网站的看法:1.既然
- 序言偶尔你们会有机会了解一件事情的来龙去脉和其中的内幕,今天你就很幸运,因为我将带你领略当今最热门,同时也可能是你已经熟悉了的技术:万维网。
- 关于Google对站群等态度,这个你得发邮件去问一下Google。我们可以看到这些类型的站群:知道CBS Interactive么,其旗下的
- B2B电子商务网站优化已经成为B2B网站网络营销策略中最基本的内容,一个整体优化状况不好的B2B电子商务平台,不仅用户发布的供求信息难为潜在
- 前言刚刚买了一台新的VPS,新买的VPS的数据盘默认没有挂载到系统上,需要我们自己来挂载的。我们给服务器添加新的硬盘的时候都需要进行挂载操作
- 国内由于国家政策的原因,域名注册变的很麻烦而且国内域名商的服务态度也不是一般的差,于是乎,全球最大的域名商godaddy(去他爹~这名字翻译
- 对于已经建设好的网站,我们该如何做呢?下面我就结合自己建设“QQ空间5.0模板”亲身经历谈一点自己粗浅的做法,也许对你有所帮助!第一、网站的
- 一、实验环境 编号项目软件及版本1操作系统CentOS62环境软件VMware 123jdk环境jdk1.8.0_1814HadoopHad
- 在上一篇博文https://www.jb51.net/article/100521.htm中未设置的openwrt无法连接外网本文增加网络设
- 网站做好后,首要考虑如何做好网站推广运营,如何网站优化,你是否考虑到以下方面,侯庆龙就着重如何优化网站,谈谈自己的做法:一、网站主题,名称,
- 在这个平台上,商家除注册后拥有自己的百变商铺外,还可以发布供求、供应信息,主动联系买家抢占商机;甚至是在搜索页上进行关键词排名及&l
- Windows服务器安全维护注意八要点1、对网站的代码进行检查,检查是否被黑客放置了网页木马和ASP木马、网站代码中是否有后门程序。2、对网
- 前言在Linux和其他类Unix操作系统中,只有root用户可以运行所有命令并在系统上执行某些关键操作,如安装和更新,删除包,创建用户和组,
- 做了几个英文站其中有成功的也有失败的今天做了个总结英文站的确比中文站更加赚钱首先十分明显的就是有更多的广告联盟只接受英文站,也有不少广告联盟
- 我是一个菜鸟站长。做站时间不长。满打满算,刚刚8个月,也想一些前辈说的一样,每天晚上12点以后睡觉。早上起来的第一件事情就是 去百度site