Еще один, на который я не могу найти ответа, и такое ощущение, что я сошел с ума.
У меня есть сценарий BASH, использующий цикл for для выполнения сложной команды (много выравниваний последовательностей белков) для большого количества файлов (~ 5000). Цикл создает операторы, которые будут выполняться, если заданы отдельно (т. Е. Скопированы из сообщения об ошибке в командную строку), но которые возвращают «нет такого файла или каталога» внутри цикла. Скрипт ниже; на самом деле есть еще несколько аргументов, но это включает некоторые типичные аргументы и аргументы файла.
#! / bin / bash
# Передать каталог с целями в виде последовательностей FASTA в качестве аргумента. # Аргументы к psiblast # Обычный db = local / db / nr / nr outfile = "/ mnt / scratch / psi-blast" e = 0.001 thread = 8 itnum = 5 pssm = "/ mnt / scratch / psi-blast / pssm. " pssm_txt = "/ mnt / scratch / psi-blast / pssm." псевдо = 0 pwa_inclusion = 0,002
Для i в $ {1} / * do filename = $ (basename $ i) "local / ncbi-blast-2.2.23 + / bin / psiblast \ -query $ {i} \ -db $ db \ -out $ { outfile} / $ {filename} .out \ -evalue $ e \ -num_threads $ themes \ -num_iterations $ itnum \ -out_pssm $ {pssm} $ filename \ -out_ascii_pssm $ {pssm_txt} $ {filename} .txt \ -pseudocount $ псевдо \ -inclusion_ethresh $ pwa_inclusion "выполнено
Выполнение этих сценариев дает "
Выполнение каждой из этих команд занимает несколько минут.
3 ответа
Попробуйте без кавычек. и ты забыл некоторые косые черты.
for i in ${1}/*
do
filename=$(basename $i)
local/ncbi-blast-2.2.23+/bin/psiblast \
-query "${i}" \
-db "$db" \
-out "${outfile}/${filename}.out" \
-evalue "$e" \
-num_threads "$threads" \
-num_iterations "$itnum" \
-out_pssm "${pssm}/$filename" \
-out_ascii_pssm "${pssm_txt}/${filename}.txt" \
-pseudocount "$pseudo" \
-inclusion_ethresh "$pwa_inclusion"
done
Наблюдаемое вами поведение произойдет, если в именах файлов, которые вы повторяете, есть пробелы. По этой причине вам нужно правильно цитировать имена файлов, как в следующем минимальном примере:
#!/bin/bash
for i in *
do
filename="$(basename "$i")"
command="ls -lah '$filename'"
echo "filename=$filename"
echo "Command = $command"
eval "$command"
done
Добавление кавычек к именам файлов не поможет при использовании цикла for. Чтобы преодолеть это, я всегда делал что-то похожее на следующий пример, когда мне нужно было перебирать имена файлов:
ls -1 directory | { while read line; do echo $line; done; }
Похожие вопросы
Новые вопросы
bash
Для вопросов о скриптах, написанных для командной оболочки Bash. Для сценариев оболочки с ошибками / синтаксическими ошибками, пожалуйста, проверьте их с помощью программы shellcheck (или на сервере веб-проверки оболочки по адресу https://shellcheck.net) перед размещением здесь. Вопросы об интерактивном использовании Bash, скорее всего, будут касаться темы Super User, а не переполнения стека.