如何在bash中同时重申两个for循环?

时间:2018-07-11 13:51:06

标签: bash loops for-loop

我正在尝试执行一个需要两个输入文件的命令,两个文件都特定于每个样本。我的解决方案是使用两个for循环:

FILES=testgroup/*split.bam
TARGETS=testgroup/*intervals

for f in $FILES
do
for t in $TARGETS
do

IndelRealigner -Input1 $f Input2 $t Output $f.realigned.bam

done
done

但是当我在第二个for循环($ t)上执行此bash循环时,第一个常数是常量,然后重复该循环。

我需要同时循环输入(即$ f Sample1和$ t Sample1,$ f Sample2和$ t Sample2)。

感谢您的帮助。

编辑:

示例样品名称和相关的输入文件:

D8.1.112.fastqAligned.out.sam.rg_added_sorted.bam.dedup.bam.split.bam D8.1.112.fastqAligned.out.sam.rg_added_sorted.bam.dedup.bam.split.bam.intervals

与此同时,我将两组文件移到了一个新目录中,以查看是否可以在一个数组中指定两个组?我迷失了如何做到这一点。到目前为止:

files=testgroup/newdir    

for f in $files
do
   for t in $files
   do
   IndelRealigner -Input1 $f Input2 $t Output $f.realigned.bam
   done
done

感谢您提供任何进一步的帮助!

3 个答案:

答案 0 :(得分:1)

一个可能的解决方案:首先将文件和目标读入数组。然后使用 one 循环同时遍历两个数组:

#!/bin/bash
files=($(ls testgroup/*split.bam))
targets=($(ls testgroup/*intervals))
len=${#files[@]}
for ((i=0;i<$len;i++))
do
  IndelRealigner -Input1 "${files[$i]}" Input2 "${targets[$i]}" Output "${files[$i]}".realigned.bam
done

但是请记住:只有当目标与文件一样多时,这才起作用。

答案 1 :(得分:1)

只需循环遍历第一组文件,并随即获得相应文件的名称:

for f in *bam; do
    IndelRealigner -Input1 "$f" -Input2 "${f}.intervals" -Output "$f.realigned.bam"
done

答案 2 :(得分:0)

您已经编写了一个嵌套循环,其行为与应有的样子完全一样:内循环是针对外循环的每次迭代执行的。但是,您想要的是一次处理两组相关文件-您需要以某种方式在一个循环中进行处理。

尝试一下:找出每个文件对共有一些f而不是尝试遍历tx that。循环遍历该x,然后从循环内的f计算出tx

您可能知道哪个文件f与哪个文件t一起,但是脚本却不知道。相关的ft文件是否具有相同的前缀?那么您需要遍历前缀列表。他们编号了吗?然后,您需要一个数字循环。它仅仅是位置问题(第一个f与第一个t并存)吗?在这种情况下,是否对列表进行排序就很重要!

没有更多信息,我们将为您提供更多帮助。