將不同目錄中的類似名稱的文件轉換為同名的單一文件

將不同目錄中的類似名稱的文件轉換為同名的單一文件

誰能幫我解決以下問題?我有大約 40 個不同物種的目錄,每個目錄都有 100 個包含直系同源序列的序列檔案。每個物種目錄的序列檔案都以類似的方式命名。我想將 40 個物種目錄的同名檔案連接成一個名稱相似的序列檔案。

例如,我有以下 3 個目錄:「Species1」、「Species2」、「Species3」。這些目錄中包含類似命名的檔案:「SequenceA.fasta」、「SequenceB.fasta」、「SequenceC.fasta」。我需要將不同 SequenceA.fasta 檔案的所有內容連接到另一個目錄中名為「SequenceA.fasta」的新檔案中。我該怎麼做呢?

我用下面的循環嘗試了它,但失敗了。文件已建立但為空白:

ls . | while read FILE; do cat ./*/"$FILE" >> ./final/"$FILE"; done

感謝您的任何建議或幫助!

(對於任何潛在的交叉發布,我很抱歉,我之前不小心在錯誤的論壇上發布了這個問題)

答案1

這個答案中有幾件事需要注意。

  1. ls如果您可以使用 shellglob模式來執行您想要的操作,則解析輸出通常是一個壞主意- 請參閱 [http://mywiki.wooledge.org/ParsingLs]。為了可移植性,我沒有使用 nullglob shell 選項,但這會使腳本稍微短一些。

  2. 您想要確保您的全域模式不太寬泛,因此您告訴cat輸入和輸出使用相同的檔案名,如果您這樣做,當您嘗試建立無限大小的檔案時,您可能會很快填滿硬碟。

  3. 如果您給出類似的模式*.fasta,但它不匹配任何文件,則*.fasta使用文字字串。

  4. 如果您有一個名為的文件*.fasta,那麼區分該文件與模式之間的差異的一種方法是查看它是否可讀。

  5. --如果可能存在惡意檔案名,那麼結束參數解析是個好主意。

首先是一個簡單的腳本。

# Simple script, assumes that "Species1" has all the needed "SequenceX.fasta" files
# Start in the directory containing "Species1", "Species2" etc.
# create output directory
mkdir "final"
# Go into the first directory
cd "Species1"
# Loop over all the files
for i in *".fasta"
do
    # join all the like named files in the sibling directories to the output
    # use a pattern which doesn't match ../final/$i to get list of files to join.
    cat "../Species"*"/$i" > "../final/$i"
done

這假設“Species1”具有所有“SequenceX.fasta”檔案。如果不是這種情況,那麼您可能需要一個雙循環。這更穩健,但更長且更慢。

# Start in the top level and loop over the directories
for dir in */
do
    # don't do anything inn the output directory
    [ "$dir" = "final" ] && continue
    # cd into directory, protecting against rogue directory names
    cd "./$dir" || { echo "cd to $dir failed" >&2 ; exit 1 ; }
    # loop over the files 
    for file in *"fasta"
    do
         # check the file exists, if there are no files matching the pattern
         # then the shell will pass the pattern through to the loop
         if [ -r "$file" ] ; then
             cat -- "$file" >> "../final/$file"
         fi
    done
    cd ".." || { echo "failed to return from $dir" ; exit 1 ; }
done

相關內容