Bash循环代替VS并行进程



我在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

我试过其他几种方法,但对我来说,这似乎是最接近正确的方法…请帮忙好吗?

Thanks in advance

更新:

我已经听取了我在评论中得到的建议,它似乎工作得很好,但我后来意识到并行过程本身不适合我,因为脚本产生的输出文件都是空的。

通过使用"平行"命令,程序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并行进程?或者其他可以很好地解决这类问题的循环?

Thanks in advance

让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

我做了一个简单的例子来展示如何运行一个可读的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

最新更新