#linux #bash
#linux #bash
Вопрос:
У меня есть код, который я пытаюсь обновить из другого примера. Цель состоит в том, чтобы запустить plink, используя файлы: каждой хромосомы, идентификаторы snp и файл, содержащий только 1 идентификатор, который является индивидуальным идентификатором. Запуск этих файлов в plink в конечном итоге создает файл vcf для каждого индивидуума для данной хромосомы.
У меня есть 22 файла хромосом, 1 snp-файл (который всегда один и тот же) и 500 отдельных файлов. Для каждого отдельного пользователя я стремлюсь создать vcf для каждой хромосомы, поэтому у меня есть 22 * 500 (11000) файлов vcf в качестве выходных данных.
Выполняя это на данный момент, я попробовал скрипт bash с этим:
ID=$SGE_TASK_ID
indiv=$SGE_TASK_ID
plink --bed chr${ID}.bed --bim chr${ID}.bim --fam chr${ID}.fam --extract snps.txt
--recode vcf-iid --out output${indiv}chr${ID}vcf --keep-fam individual${indiv}.txt
Это выполняется, однако оно выполняется только через 1 человека, предоставляя мне 22 файла vcf хромосом для этого одного человека, и на этом останавливается. Как мне запустить это для всех 500 пользователей, будет ли это с циклом for? Просматривая другие вопросы, я не смог найти тот, который соответствует моему вопросу и находится в Linux, буду признателен за любую помощь.
${indiv} было бы просто числом, поэтому выполняемый текстовый файл выглядит как individual1.txt и увеличивается на 500 человек (individual1.txt , individual2.txt , individual3.txt )
Ответ №1:
Предполагая, что ${indiv}
не содержит пробелов,
for indiv in $(<individuals.data); do
plink [...] individual${indiv}.txt
done
В файле individuals.data
будут указаны имена отдельных пользователей, разделенные пробелами или символами новой строки.
Если вы не уверены, что делает $(<...)
оператор оболочки Bash, попробуйте это:
for A in $(<individuals.data); do
echo "[$A]"
done
Обратите внимание, что, как заметил @Kaz, если вы хотите, чтобы ваш скрипт работал также в оболочках, отличных от Bash, тогда вы могли бы написать $(cat ...)
вместо $(<...)
Комментарии:
1. Нет необходимости делать это предположение (и это не будет единственным предположением, которое вам нужно сделать для использования
for
). Смотрите Bash FAQ 001 .2. @chepner Интересно. Я использую
for
для таких целей без инцидентов с 2004 года или около того, вероятно, сотни раз; но я, безусловно, готов к тому, чтобы меня научили лучшему способу работы. Однако я думаю , что вы ошибаетесь насчет пробелов.3. Более точно
$(< ...)
является оператором GNU Bourne-Again Shell. Переносимый эквивалент$(cat ...)
. В документации Bash утверждается, что$(< ...)
это более быстрый эквивалент для$(cat ...)
. Это совершенно глупо; Bash должен просто взять$(cat ...)
синтаксис и перевести его в$(< ...)
, а не заставлять программиста делать это в исходном коде. Посколькуcat
это стандартная утилита, реализация оболочки может рассматривать ее как встроенную. Как только Bash будет исправлен для этого,$(< ...)
синтаксис станет историческим ключом.4. @Kaz Теперь ответ объединяет ваши наблюдения.
5. @tbh Если строка из файла содержит мета-символы типа
*
или?
, слова подлежат сопоставлению с шаблоном, поскольку замена команды не заключена в кавычки.