【问题标题】:Bash loops instead VS parallel processesBash 循环而不是 VS 并行进程
【发布时间】:2021-05-09 14:15:19
【问题描述】:

我在 bash 中使用 cat+pipe+parallel 编写了一个简单的脚本,但由于大量输入数据 (>200) 我的计算机崩溃了。但是,它仅适用于少数文件 (2)。 建议我使用“for”或“foreach”循环来避免崩溃,但我正在努力将我的脚本转换为循环。

DATADIR 中的输入文件:

FAO21783_pass_c04106c7_0.fastq

FAO21783_pass_c04106c7_1.fastq

FAO21783_pass_c04106c7_2.fastq

FAO21783_pass_c04106c7_3.fastq

FAO21783_pass_c04106c7_4.fastq

等等……

原始脚本(使用并行)并且运行良好:

    #!/bin/zsh -x

    DATADIR=shimbok_data/SB1_F2_data/fastq_pass

    DATAOUT=shimbok_data/SB1_F2_data/output

    DATABASEDIR=kaijudb

    DATABASE=kaijudb/refseq/kaiju_db_refseq.fmi

runinfo.txt 包含 DATADIR 中的文件列表

    cat shimbok_data/SB1_F2_data/runinfo.txt | parallel kaiju -t ${DATABASEDIR}/nodes.dmp -f ${DATABASE} -i ${DATADIR} -o ${DATAOUT}/{}.out

我正在尝试将其转换为循环,但输出文件名有问题。我希望它们像输入文件一样被调用,但扩展名为 .out(我想要 FAO21783_pass_c04106c7_0.fastq.out)

这是我能做的:

    for file in shimbok_data/SB1_F2_data/fastq_pass
      do kaiju -t ${DATABASEDIR}/nodes.dmp -f ${DATABASE} -i ${file} -o ${DATAOUT}/${file}.out
    done

它写入的输出错误:shimbok_data/SB1_F2_data/output/shimbok_data/SB1_F2_data/fastq_pass.out

我尝试了其他几种方法,但对我来说,这似乎是最接近正确的方法...请帮忙?

提前致谢

更新:

我听取了我在评论中得到的建议,它似乎工作正常,但后来我意识到并行过程本身对我不起作用,因为脚本生成的输出文件都是空的。

通过使用“并行”命令,Kaiju 程序使用 runinfo.txt 列表,但要正常工作,它需要使用 DATADIR 中的实际文件 (fastq)...

与此同时,我发现了一个适合我的情况的循环:

      set num = 0
      set num_e = 266


      while ( $num < $num_e )
        set xx = `printf ${num}`
        echo xx

      kaiju -t ${DATABASEDIR}/nodes.dmp -f ${DATABASE} -i 
      ${DATADIR}/FAO21783_pass_c04106c7_${xx}.fastq -o 
      ${DATAOUT}/FAO21783_pass_c04106c7_${xx}.out

         @ num++
         end

有没有办法使用 GNU 并行进程进行相同的迭代?或者其他可以很好地解决此类问题的循环?

提前致谢

【问题讨论】:

    标签: loops parallel-processing fastq


    【解决方案1】:

    让 GNU Parallel “并行”运行一个作业怎么样:

    cat shimbok_data/SB1_F2_data/runinfo.txt |
      parallel -j1 kaiju -t ${DATABASEDIR}/nodes.dmp -f ${DATABASE} -i ${DATADIR} -o ${DATAOUT}/{}.out
    

    或 2:

    cat shimbok_data/SB1_F2_data/runinfo.txt |
      parallel -j2 kaiju -t ${DATABASEDIR}/nodes.dmp -f ${DATABASE} -i ${DATADIR} -o ${DATAOUT}/{}.out
    

    【讨论】:

      【解决方案2】:

      我正在做一个简单的例子来展示如何运行一个可读的 for 循环。像这样准备你的“假”文件:

      mkdir my-input-dir
      cd my-input-dir
      touch file1.txt  file2.txt  file3.txt  file4.tmp
      cd ..
      mkdir my-out-dir
      

      您的目录结构应该如下所示(我自愿创建了一个.tmp 文件来展示如何过滤循环):

      $ : tree .
      ├── my-input-dir
      │   ├── file1.txt
      │   ├── file2.txt
      │   ├── file3.txt
      │   └── file4.tmp
      └── my-out-dir
      

      touch 命令创建一个空文件,这就是为什么对演示很有用。

      现在,为了模仿您需要做的事情,我创建了一个脚本,该脚本基于输入文件创建具有相同名称和 .out 扩展名的输出文件(例如 file.txt -> file1.out)。

      INPUT_DIR=./my-input-dir
      OUTPUT_DIR=./my-out-dir
      for file in `ls $INPUT_DIR/*.txt`
      do
        BASENAME=$(basename $file .txt)
        OUTFILE="$OUTPUT_DIR/$BASENAME.out"
        touch $OUTFILE
      done
      

      那么你就可以在my-out-dir找到生成的文件了:

      $ : ls $OUTPUT_DIR
      file1.out  file2.out  file3.out
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-14
        • 2023-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-11
        相关资源
        最近更新 更多