Как повторить более двух циклов for одновременно в bash?

Я пытаюсь выполнить команду, которой нужны два входных файла, каждый из которых специфичен для каждого образца. Мое решение состояло в том, чтобы использовать два цикла 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

Но когда я выполняю этот цикл bash по второму циклу for ($t) с первым постоянным, затем цикл повторяется.

Мне нужно, чтобы входные данные зацикливались одновременно (т. е. $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

Любая дальнейшая помощь приветствуется!


person FatBerg    schedule 11.07.2018    source источник
comment
Вы написали цикл в цикле. Сделайте отступ в своем коде, и это может быть более ясно. Loop1 - iteration1, будут выполняться все итерации Loop2. То же самое касается Loop1 - iteration2. Вам нужно будет установить какую-то связь между FILES и TARGETS, чтобы вы могли сделать это в одном цикле. Подумайте, что вы решите это вручную и примените это к коду. Возможно, поделитесь некоторыми образцами имен файлов/целей, и, возможно, мы сможем помочь выяснить этот шаблон/отношение. Кроме того... избегайте имен ваших переменных в верхнем регистре, так как переменные в верхнем регистре зарезервированы для системы.   -  person JNevill    schedule 11.07.2018
comment
Спасибо за совет, я обновил свой пост.   -  person FatBerg    schedule 11.07.2018


Ответы (3)


Одно из возможных решений: сначала читать файлы и цели в массивы. Затем используйте цикл один для одновременного прохода по обоим массивам:

#!/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

Но имейте в виду: это сработает, только если целей столько же, сколько файлов.

person Rene Knop    schedule 11.07.2018
comment
Спасибо, но у меня не работает. Я не могу точно определить, что не так, но возвращаемые сообщения об ошибках предполагают, что он пытается ввести все файлы «Ввод 1» одновременно. - person FatBerg; 11.07.2018
comment
Ты прав. Скрипт немного глючил. Я починил это. Пожалуйста, попробуйте еще раз. :-) - person Rene Knop; 11.07.2018

Просто переберите первый набор файлов и получите имя соответствующего файла по ходу дела:

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

Вы написали вложенный цикл, и его поведение именно такое, каким оно должно быть: внутренний цикл выполняется для каждой итерации внешнего цикла. Но вам нужно обработать два набора связанных файлов за один проход — вам нужно каким-то образом сделать это в одном цикле.

Попробуйте следующее: вместо того, чтобы пытаться перебирать f и t, определите, что некоторые x that являются общими для каждой пары файлов. Зациклитесь на этом x и вычислите f и t из этого x внутри цикла.

ВЫ можете знать, какой файл f идет с каким файлом t, но скрипт этого не знает. Имеют ли связанные файлы f и t один и тот же префикс? затем вам нужно перебрать список префиксов. Они пронумерованы? Тогда вам нужен числовой цикл. Это просто позиционная вещь (первая f идет с первой t)? В этом случае имеет значение, сортируете ли вы списки или нет!

Без дополнительной информации мы не сможем помочь вам более чем в общих чертах.

person Angelo Wentzler    schedule 11.07.2018
comment
Спасибо за помощь. Я обновил свой пост. Входные файлы имеют общий префикс («D8.1.112» меняется с каждой парой), но я изо всех сил пытаюсь понять, как это реализовать. - person FatBerg; 11.07.2018