Как использовать для цикла с несколькими переменными в Linux - PullRequest
0 голосов
/ 28 января 2019

У меня есть команда, которую нужно запустить для нескольких комбинаций файлов.Команда выглядит следующим образом:

myscript.pl -output_directory /path/output_"$TARGET_SAMPLE"_vs_"$NORMAL_SAMPLE" -target_sample /path/$TARGET_SAMPLE.bam -normal_sample /path/$NORMAL_SAMPLE.bam

Я хочу выполнить это для нескольких наборов выборок без необходимости каждый раз вручную изменять пути.Прямо сейчас я устанавливаю сэмплы перед тем, как запускать их вручную, как это:

export TARGET_SAMPLE="sample_1"
export NORMAL_SAMPLE="sample_2"

Как мне запустить это, чтобы убедиться, что TARGET_SAMPLE и NORMAL_SAMPLE всегда правильно сопоставлены?Для каждого NORMAL_SAMPLE мне нужно дважды запустить скрипт с двумя разными файлами TARGET_SAMPLE.Я думаю, что использование массива может сработать, но я не знаю, как правильно передать это в цикл for.

Вот несколько примеров пар, которые мне нужно выполнить:

export TARGET_SAMPLE="sample_1"
export NORMAL_SAMPLE="sample_2"

export TARGET_SAMPLE="sample_3"
export NORMAL_SAMPLE="sample_2"

export TARGET_SAMPLE="sample_4"
export NORMAL_SAMPLE="sample_5"

export TARGET_SAMPLE="sample_6"
export NORMAL_SAMPLE="sample_5"

Таким образом, первый пример выходных данных из этого списка комбинаций будет представлять эти команды в оболочке:

myscript.pl -output_directory /path/output_sample_1_vs_sample_2 -target_sample /path/sample_1.bam -normal_sample /path/sample_2.bam

и второй будет:

myscript.pl -output_directory /path/output_sample_3_vs_sample_2 -target_sample /path/sample_3.bam -normal_sample /path/sample_2.bam

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 28 января 2019

Метод 1 с использованием цикла while для чтения нескольких значений из «здесь-документа»:

export TARGET_SAMPLE NORMAL_SAMPLE

# special characters in the values (eg. space) will cause problems
while read TARGET_SAMPLE NORMAL_SAMPLE ANYTHING_ELSE; do
    # insert sanity checks here
    myscript.pl -output_directory /path/output_"$TARGET_SAMPLE"_vs_"$NORMAL_SAMPLE" -target_sample /path/$TARGET_SAMPLE.bam -normal_sample /path/$NORMAL_SAMPLE.bam
done <<'EOD'
sample_1 sample_2
sample_3 sample_2
sample_4 sample_5
sample_6 sample_5
EOD

Метод 1b в качестве метода 1, но чтение данных из внешнего файла:

# spcial characters in the values (eg. space) will cause problems
cat >mydata <<'EOD'
sample_1 sample_2
sample_3 sample_2
sample_4 sample_5
sample_6 sample_5
EOD

export TARGET_SAMPLE NORMAL_SAMPLE

# normally $ANYTHING_ELSE should be empty but embedded spaces will confuse read
cat mydata | while read TARGET_SAMPLE NORMAL_SAMPLE ANYTHING_ELSE; do
    # insert sanity checks here
    myscript.pl -output_directory /path/output_"$TARGET_SAMPLE"_vs_"$NORMAL_SAMPLE" -target_sample /path/$TARGET_SAMPLE.bam -normal_sample /path/$NORMAL_SAMPLE.bam
done

Обработка метода 2 с помощью функции оболочки:

export TARGET_SAMPLE NORMAL_SAMPLE

wrapper(){
    TARGET_SAMPLE=$1
    NORMAL_SAMPLE=$2
    # insert sanity checks here
    myscript.pl -output_directory /path/output_"$TARGET_SAMPLE"_vs_"$NORMAL_SAMPLE" -target_sample /path/$TARGET_SAMPLE.bam -normal_sample /path/$NORMAL_SAMPLE.bam
}

wrapper "sample_1" "sample_2"
wrapper "sample_3" "sample_2"
wrapper "sample_4" "sample_5"
wrapper "sample_6" "sample_5"

Метод 3, использующий цикл for для нескольких массивов:

Bash имеет индексированные переменные массива, поэтому возможен цикл for, но поддержание синхронизации массивовподвержен ошибкам, поэтому я не рекомендую его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...