并行许多文件的bash脚本

时间:2015-11-24 14:59:58

标签: bash parallel-processing

我已经阅读过有关此主题的类似问题,但没有一个能帮助我解决以下问题:

我有一个看起来像这样的bash脚本:

#!/bin/bash

for filename  in /home/user/Desktop/emak/*.fa; do
    mkdir ${filename%.*}
    cd ${filename%.*}
    mkdir emak
    cd ..
done

此脚本基本上执行以下操作:

  • 遍历目录中的所有文件
  • 使用每个文件的名称创建一个新目录
  • 进入新文件并创建一个名为" emak"
  • 的新文件

真正的任务比计算" emak"文件...

我有大约数千个要迭代的文件。 由于每次迭代都独立于前一次,我想 将它拆分到不同的处理器(我有24个核心)所以我可以同时做多个文件。

我读过一些关于并行运行的帖子(使用:GNU)但我没有看到在这种情况下应用它的明确方法。

谢谢

2 个答案:

答案 0 :(得分:2)

GNU Parallel这样的东西,你创建并导​​出一个名为doit的bash函数:

#!/bin/bash

doit() {
    dir=${1%.*}
    mkdir "$dir"
    cd "$dir"
    mkdir emak
}
export -f doit
parallel doit ::: /home/user/Desktop/emak/*.fa

如果&#34;计算成本高昂的&#34; 部分花费的时间更长,或者特别是变量,您将真正看到这种方法的好处。如果需要,比如最多10秒并且是可变的,GNU Parallel将在N个并行进程中的最短时间完成后立即提交下一个作业,而不是在开始下一批N个作业之前等待所有N完成。< / p>

作为一个粗略的基准,这需要58秒:

#!/bin/bash

doit() {
   echo $1
   # Sleep up to 10 seconds
   sleep $((RANDOM*11/32768))
}
export -f doit
parallel -j 10 doit ::: {0..99}

这可以直接比较,需要87秒:

#!/bin/bash
N=10
for i in {0..99}; do
    echo $i
    sleep $((RANDOM*11/32768)) &
    (( ++count % N == 0)) && wait
done

答案 1 :(得分:1)

不需要parallel;你可以简单地使用

N=10
for filename in /home/user/Desktop/emak/*.fa; do
    mkdir -p "${filename%.*}/emak" &
    (( ++count % N == 0)) && wait
done

第二行暂停每个第N个作业,以便在继续之前完成所有先前的作业。