Использование цикла bash для запуска программы, которая использует одинарные кавычки в командной строке, где одинарные кавычки сводят на нет намерения сценария bash

Эта проблема:

Я хочу иметь возможность запускать программу внутри цикла bash для каждого файла .fna в каталоге, но я также хочу, чтобы имя выходного файла имело то же имя файла (без расширения), проблема в том, что программа использует одинарные кавычки для указания своего выходного файла. Поэтому, когда я запускаю свой скрипт, он просто печатает файл с именем:

outputfile 

Код:

  for fna in $(find . -name "*.fna") do outputname = ${fna%.fna} outputfile = $outputname.rrna barrnap $fna --outseq 'outputfile' done 

Пример ввода

Файл с именем:

 GCF_000003135.1_ASM313v1_genomic.fna 

С примером содержания:

 >NZ_GG666849.1 Bifidobacterium longum subsp. longum ATCC 55813 SCAFFOLD1, whole genome shotgun sequence AACCCCGTGGAGTTCACACAACAAGGTGTATTTAGTCAAGTCGGTGTTTCGTGTTTCGTCACTGATTTTTTTCACTGCGG AAA 

Желаемый вывод:

Выходной файл из программы с именем:

 GCF_000003135.1_ASM313v1_genomic.rrna 

Я прошу прощения за беспорядок, у меня возникли проблемы с поиском лучшего способа объяснения проблемы, если кто-то может предложить мне улучшение названия, я немедленно его заменю.

    Программа не использует одинарные кавычки. Одинарные кавычки используются для предотвращения выполнения оболочкой переменных в строке в кавычках. Кавычки будут удалены оболочкой перед вызовом программы.

    В этом случае одинарные кавычки ничего не делают, так как строка, которую они заключают в кавычки, является простой строкой без расширений для выполнения оболочки (это ошибка в вашем коде, вы, вероятно, хотели получить $outputfile с двойными кавычками).

    Если ваши файлы находятся в текущем каталоге (и только там), вы можете сделать

     for fasta in ./*.fna; do barrnap --outseq "${fasta%.fna}.rrna" "$fasta" done 

    или, с промежуточной переменной,

     for fasta in ./*.fna; do outfile="${fasta%.fna}.rrna" barrnap --outseq "$outfile" "$fasta" done 

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

    Если ваши файлы находятся в любом количестве подкаталогов в текущем каталоге, и вам нужно использовать find , не перебирайте вывод find но позвольте find вызвать вашу программу:

     find . -type f -name '*.fna' -exec sh -c ' for fasta do barrnap --outseq "${fasta%.fna}.rrna" "$fasta" done' sh {} + 

    Здесь find действует как генератор путей для цикла оболочки.

    Связанные с:

    • Почему зацикливание на выводе find плохо работает?
    • Понимание опции -exec `find`

    В вашем коде также есть пара синтаксических ошибок, которые должны выполняться без пробелов вокруг = . Кроме того, расширения переменных должны быть заключены в двойные кавычки.