我有一个文本文件infile.txt
,如下所示:
abc what's the foo bar.
foobar hello world, hhaha cluster spatio something something.
xyz trying to do this in parallel
kmeans you're mean, who's mean?
文件中的每一行都将由这个perl命令处理到out.txt中
`cat infile.txt | perl dosomething > out.txt`
假设文本文件有100,000,000行,我想并行化bash命令,所以我尝试了如下操作:
$ mkdir splitfiles
$ mkdir splitfiles_processed
$ cd splitfiles
$ split -n3 ../infile.txt
$ for i in $(ls); do "cat $i | perl dosomething > ../splitfiles_processed/$i &"; done
$ wait
$ cd ../splitfiles_processed
$ cat * > ../infile_processed.txt
但是,有没有一种不那么冗长的方法来做同样的事情呢?
3条答案
按热度按时间azpvetkf1#
@Ulfalizer的回答给了你一个关于解决方案的很好的提示,但缺少一些细节。
您可以使用GNU parallel(Debian上的
apt-get install parallel
)因此,您的问题可以使用以下命令解决:
以下是这些参数的含义:
t9aqgxwy2#
我自己从来没有试过,但是GNU parallel可能值得一试。
下面是从手册页(
parallel(1)
)中摘录的内容,它与您当前所做的类似,也可以用其他方式分割输入。这是否值得取决于你的CPU密集型处理,对于简单的脚本,你将花费大部分时间在磁盘上来回移动数据,并行化不会给你带来太多好处。
您可以找到GNU Parallel作者here的一些介绍性视频。
bxgwgixi3#
假设您的限制因素不是磁盘,您可以在perl中使用
fork()
,特别是Parallel::ForkManager
来完成此操作:然而,这样做的缺点是合并输出,每个并行任务并不一定按照它开始的顺序完成,所以在序列化结果时会有各种各样的潜在问题。
您可以使用
flock
之类的解决方案来解决这些问题,但您需要小心,因为过多的锁定操作首先会使您失去并行优势(因此我的第一句话是-如果您的限制因素是磁盘IO,那么并行性无论如何都不会有多大帮助)。有各种可能的解决方案,虽然-这么多,写了整整一章,它在perl文档:perlipc-但请记住,您也可以使用
Parallel::ForkManager
检索数据。