Bash для циклов - как использовать переменную $ {file}? - PullRequest
0 голосов
/ 30 сентября 2019

Я хотел бы запустить команду для списка парных файлов в следующем формате

SAMPLE_1.1.fq.gz SAMPLE_1.2.fq.gz
SAMPLE_2.1.fq.gz SAMPLE_2.2.fq.gz

и т. Д.

и т. Д. Это в каталоге с именем ../cleaned-trimmed

У меня есть список сэмплов в текстовом файле (samples_final.txt - один сэмпл на строку) в каталоге с именем info.

SAMPLE_1
SAMPLE_2
SAMPLE_3

Я хотел бы выполнить следующую команду для всех примеров:

gsnap <args> --output-file=./alignments.gsnap/SAMPLE_1.mapped.sam --failed-input=./alignments.gsnap/SAMPLE_1.unmapped.fa ../cleaned-trimmed/SAMPLE_1.1.fq.gz ../cleaned-trimmed/SAMPLE_1.2.fq.gz

Где аргументы - это используемая база данных, флаги команд и т. Д.

Я изменил скрипт изпредыдущий ответ в stackoverflow, чтобы построить цикл следующим образом:

for file in $(<../info/samples_final.txt)
do
gsnap <args> --output-file=./alignments.gsnap/${file}.mapped.sam --failed-input=./alignments.gsnap/${file}.unmapped.fa ../cleaned-trimmed/${file}.1.fq.gz ../cleaned-trimmed/${file}.2.fq.gz
done

, но он не передает переменные правильно.

Как передать значения из samples_final.txt в команду? На данный момент сценарий искажает имена файлов, когда я запускаю цикл. Так, например, если я запускаю тест для файла "for_test2.txt":

SAMPLE_1
SAMPLE_2

Используя команду echo:

for file in $(<../info/for_test2.txt)
do
   echo ../cleaned-trimmed/${file}.1.fq.gz
done

, я получаю следующий вывод:

.1.fq.gzed-trimmed/SAMPLE_1
.1.fq.gzed-trimmed/SAMPLE_2
.1.fq.gzed-trimmed/

Так что, похоже, он заменил ../clean на .1.fq.gz

Я искренне не понимаю логику этого.

1 Ответ

1 голос
/ 30 сентября 2019

В вашем файле есть окончания строки DOS. Символ «возврат носителя» заставляет курсор перейти к началу текущей строки, поэтому часть .1.fq.gz в вашем последнем отсканированном коде напечатана в начале строки. Сначала вы можете преобразовать ваш файл в обычное окончание строки:

dos2unix ../info/for_test2.txt

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

while IFS= read -r file; do
   # protect against empty lines in input file
   if [ -z "$file" ]; then continue; fi

   gsnap <args> --output-file=./alignments.gsnap/"$file".mapped.sam --failed-input=./alignments.gsnap/"$file".unmapped.fa ../cleaned-trimmed/"$file".1.fq.gz ../cleaned-trimmed/"$file".2.fq.gz
done <../info/for_test2.txt

или как профессионал с xargs:

<../info/for_test2.txt xargs -I{} gsnap <args> --output-file=./alignments.gsnap/{}.mapped.sam --failed-input=./alignments.gsnap/{}.unmapped.fa ../cleaned-trimmed/{}.1.fq.gz ../cleaned-trimmed/{}.2.fq.gz
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...