使用 bash 循环运行在命令行中使用单引号的程序,其中单引号使 bash 脚本的意图无效

使用 bash 循环运行在命令行中使用单引号的程序,其中单引号使 bash 脚本的意图无效

问题:

我希望能够在目录中的每个 .fna 文件上的 bash 循环中运行程序,但我也希望输出文件的名称具有相同的文件名(不带扩展名),问题是该程序使用单引号指定其输出文件。因此,当我运行脚本时,它只打印一个名为:

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

我对此的混乱表示抱歉,我很难想出最好的方法来解释这个问题,如果有人能建议我改进标题,我会立即更改它。

答案1

该程序不使用单引号。单引号用于防止 shell 对带引号的字符串执行变量扩展。在调用程序之前,shell 将删除引号。

在这种情况下,单引号不会执行任何操作,因为它们引用的字符串只是一个普通字符串,没有供 shell 执行的扩展(这是代码中的错误,您可能需要$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它的作用就像 shell 循环的路径名生成器。

有关的:


您的代码还存在一些语法错误,因为分配时应该在 . 周围没有空格=。此外,变量扩展应该用双引号引起来。

相关内容