Bash

使用 bash 循環執行在命令行中使用單引號的程序,其中單引號使 bash 腳本的意圖無效

  • September 4, 2018

問題:

我希望能夠在 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

我為這個混亂道歉,我很難想到解釋問題的最佳方式,如果有人可以向我建議改進標題,我會立即改變它。

該程序不使用單引號。單引號用於防止 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 循環的路徑名生成器。

有關的:


您的程式碼也有幾個語法錯誤,因為分配應該在=. 此外,變數擴展應該用雙引號引起來。

引用自:https://unix.stackexchange.com/questions/466724