使用GNU Parallel并行化嵌套for循环

3

我正在使用Bash进行工作。我有一系列嵌套的for循环,迭代地查找三个96个条形码序列列表的存在。我的目标是找到每个独特的条形码组合,共有96x96x96(884,736)种可能的组合。

for barcode1 in "${ROUND1_BARCODES[@]}";
do
grep -B 1 -A 2 "$barcode1" $FASTQ_R > ROUND1_MATCH.fastq
echo barcode1.is.$barcode1 >> outputLOG

    if [ -s ROUND1_MATCH.fastq ]
    then

        # Now we will look for the presence of ROUND2 barcodes in our reads containing barcodes from the previous step
        for barcode2 in "${ROUND2_BARCODES[@]}";
        do
        grep -B 1 -A 2 "$barcode2" ROUND1_MATCH.fastq > ROUND2_MATCH.fastq

            if [ -s ROUND2_MATCH.fastq ]
            then

                # Now we will look for the presence of ROUND3 barcodes in our reads containing barcodes from the previous step 
                for barcode3 in "${ROUND3_BARCODES[@]}";
                do
                grep -B 1 -A 2 "$barcode3" ./ROUND2_MATCH.fastq | sed '/^--/d' > ROUND3_MATCH.fastq

                # If matches are found we will write them to an output .fastq file itteratively labelled with an ID number
                if [ -s ROUND3_MATCH.fastq ]
                then
                mv ROUND3_MATCH.fastq results/result.$count.2.fastq
                fi

                count=`expr $count + 1` 
                done
            fi
        done
    fi
done

这段代码可以正常运行,我能够成功地提取每个条形码组合的序列。然而,我认为通过并行化循环结构,可以提高处理大文件的速度。我知道可以使用GNU parallel来实现这一点,但是我在嵌套并行化方面遇到了困难。

# Parallelize nested loops
now=$(date +"%T")
echo "Beginning STEP1.2: PARALLEL Demultiplex using barcodes. Current 
time : $now" >> outputLOG

mkdir ROUND1_PARALLEL_HITS
parallel -j 6 'grep -B 1 -A 2 -h {} SRR6750041_2_smalltest.fastq > ROUND1_PARALLEL_HITS/{#}_ROUND1_MATCH.fastq' ::: "${ROUND1_BARCODES[@]}"

mkdir ROUND2_PARALLEL_HITS
parallel -j 6 'grep -B 1 -A 2 -h {} ROUND1_PARALLEL_HITS/*.fastq > ROUND2_PARALLEL_HITS/{#}_{/.}.fastq' ::: "${ROUND2_BARCODES[@]}"

mkdir ROUND3_PARALLEL_HITS
parallel -j 6 'grep -B 1 -A 2 -h {} ROUND2_PARALLEL_HITS/*.fastq > ROUND3_PARALLEL_HITS/{#}_{/.}.fastq' ::: "${ROUND3_BARCODES[@]}"

mkdir parallel_results
parallel -j 6 'mv {} parallel_results/result_{#}.fastq' ::: ROUND3_PARALLEL_HITS/*.fastq

如何使用并行方式成功地重新创建for循环的嵌套结构?


如果您不介意的话,可以使用 xargs -P 0 命令,它会自动创建所需数量的线程。我正在使用 xargs 将多个 mp4 文件转换为 mp3,性能有了很大提升。parallel 的功能相同,但语法稍微复杂一些。 - Shakiba Moshiri
1个回答

2

仅对内部循环进行并行化:

for barcode1 in "${ROUND1_BARCODES[@]}";
do
grep -B 1 -A 2 "$barcode1" $FASTQ_R > ROUND1_MATCH.fastq
echo barcode1.is.$barcode1 >> outputLOG

    if [ -s ROUND1_MATCH.fastq ]
    then

        # Now we will look for the presence of ROUND2 barcodes in our reads containing barcodes from the previous step
        for barcode2 in "${ROUND2_BARCODES[@]}";
        do
        grep -B 1 -A 2 "$barcode2" ROUND1_MATCH.fastq > ROUND2_MATCH.fastq
            if [ -s ROUND2_MATCH.fastq ]
            then
                # Now we will look for the presence of ROUND3 barcodes in our reads containing barcodes from the previous step 
                doit() {
                    grep -B 1 -A 2 "$1" ./ROUND2_MATCH.fastq | sed '/^--/d'
                }
                export -f doit
                parallel -j0 doit {} '>' results/$barcode1-$barcode2-{} ::: "${ROUND3_BARCODES[@]}"
                # TODO remove files with 0 length
            fi
        done
    fi
done

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