如何使用 for 迴圈從各種檔案中刪除 . 副檔名之前的四個隨機字元?

如何使用 for 迴圈從各種檔案中刪除 . 副檔名之前的四個隨機字元?

我正在從事一個以生物資訊為主的本科研究項目,並且正在進行文件處理的流程。一些背景:我正在處理鳥槍法宏基因組數據,這些數據是非常大的 A、T、G、C(DNA 樣本中的核苷酸)樣本,以及我收集到的一些限定符。我已經完成了管道的幾個步驟,其中修剪和清理了一些文件,並添加了一些限定符。重要的是,這些讀數大多是配對末端讀數,這意味著兩個文件從右到左和從左到右讀取核苷酸。

在此之前,我的腦子裡基本上只有生物學和生態學,所以我真的沒有任何編碼背景,或者如何/為什麼做事或常見實踐/功能等。

也就是說,我自學了 UNIX 中非常基本的 for 迴圈和字串操作,製作了一些使用不同模組和函數在不同資料夾中執行的 bash 檔案。這是範例程式碼:

cd ~/ncbi/public/sra/indian

for forward_read_file in *_1.fastq

do
rev=_2
reverse_read_file=${forward_read_file/_1/$rev}
perl /home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/AmbiguityFiltering.pl -i ${forward_read_file} -irev ${reverse_read_file} -c 1 -t5 -t3

rm ${forward_read_file} ${reverse_read_file}
done

#CAMEROON
cd ~/ncbi/public/sra/cameroon

for forward_read_file in *_1.fastq

do
rev=_2
reverse_read_file=${forward_read_file/_1/$rev}
perl /home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/AmbiguityFiltering.pl -i ${forward_read_file} -irev ${reverse_read_file} -c 1 -t5 -t3

rm ${forward_read_file} ${reverse_read_file}
done 

對於許多資料夾等等。我使用字串操作來獲取 for 循環的每次迭代來調用配對的最終文件,然後是我正在使用的模組的一些參數和參數。

我現在遇到的大問題是,我想不出一種方法來為管道中的下一步配對配對的最終文件,因為它們在擴展名之前有四個隨機字符,而且我無法預測它們。它們不包含有意義的數據,因此我的計劃是將它們從文件名中刪除並像以前一樣繼續。

以下是問題文件的範例;問題是字串末尾的四個字元。如果我擺脫那些我可以像往常一樣進行字串操作。

SRR5898908_1_prinseq_good_ZsSX.fastq  SRR5898928_2_prinseq_good_VygO.fastq  SRR5898979_1_prinseq_good_CRzI.fastq  SRR6166642_2_prinseq_good_nqVP.fastq  SRR6166693_2_prinseq_good_y_OD.fastq
SRR5898908_2_prinseq_good_HPTU.fastq  SRR5898929_1_prinseq_good_p2mS.fastq  SRR5898979_2_prinseq_good_vYcE.fastq  SRR6166643_1_prinseq_good_fc8y.fastq  SRR6166694_1_prinseq_good_Ka1C.fastq
SRR5898909_1_prinseq_good_X41r.fastq  SRR5898929_2_prinseq_good_uO8g.fastq  SRR5898980_1_prinseq_good_WuPS.fastq  SRR6166643_2_prinseq_good_QUUK.fastq  SRR6166694_2_prinseq_good_ZlNk.fastq
SRR5898909_2_prinseq_good_GbmA.fastq  SRR5898930_1_prinseq_good_3qyA.fastq  

其中開頭的 SRRxxxxx 是樣本,而1或者2分別是正向和反向讀取,因此是我的字串操作。問題是字串末尾的四個字元。如果我擺脫那些我可以像往常一樣進行字串操作。我的導師建議我以某種方式使用 FIND 或 CUT 函數,並談到使用 find 的返回作為操作變量,但我覺得這仍然會遇到相同的問題。

如何使用 for 迴圈安全地刪除這些字元?或任何你認為最有效的方法。

謝謝你!

答案1

試試這樣的事情:

for forward_read_file in *_1*.fastq; do
   srr=$(echo "$forward_read_file" | cut -d_ -f1)
   rrf_array=( $(find . -name "${srr}_2_*.fastq") )

   case "${#rrf_array[@]}" in
     0) echo "Warning: No reverse read file found for $forward_read_file" > /dev/stderr ;;

     1) reverse_read_file="${rrf_array[1]}"
        perl /home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/AmbiguityFiltering.pl -i "$forward_read_file" -irev "$reverse_read_file" -c 1 -t5 -t3
        ;;

     *) echo "Error: multiple reverse read files found for $forward_read_file" > /dev/stderr ;;
   esac

done

這會迭代所有_1文件。它用於cut提取 SRR 樣本 ID,然後將其與find命令一起使用來查找任何匹配的_2文件。 find的輸出儲存在陣列中,因為我們不知道可能會傳回多少結果。

它處理三種可能的結果 - 沒有匹配(不好)、恰好 1 個匹配(好,這就是我們想要的)和超過 1 個匹配(同樣,不好)。

如果只有一個結果,請從數組中提取匹配的檔案並使用 perl 腳本對其進行處理。

如果有零個或多個結果,則將警告訊息列印到 stderr 並繼續處理下一個_1檔案名稱。如果您願意,您可以在這些情況; exit 1之前新增(或其他程式碼來處理錯誤) 。;;

這將忽略檔案名稱的所有部分,除了開頭的 SRR 樣本 id 以及將其標識為正向或反向配對檔案的_1或。_2

if; then; else順便說一句,這可以用 an 而不是聲明來完成case,但我認為以不同的方式處理零個和多個案例很有用。例如

if [ "${#rrf_array[@]}" == 1 ]; 
  reverse_read_file="${rrf_array[1]}"
  perl /home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/AmbiguityFiltering.pl -i "$forward_read_file" -irev "$reverse_read_file" -c 1 -t5 -t3
else
  echo "Warning: unknown problem with reverse read file for $forward_read_file" > /dev/stderr
fi

如果您只想忽略“問題”文件,請刪除該else區塊。


順便說一句,為了使您的腳本更具可讀性,我建議在腳本頂部附近執行類似的操作:

AFilter='/home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/AmbiguityFiltering.pl'

然後:

perl "$AFilter" -i "$forward_read_file" -irev "$reverse_read_file" -c 1 -t5 -t3

或者,如果 perl 腳本是可執行的(即使用#!/usr/bin/perl或類似的 shebang 行,並且使用 來設定可執行標誌chmod +x),則只需新增/home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/至 $PATH 即可:

PATH="$PATH:/home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming"

並將腳本運行為:

AmbiguityFiltering.pl -i "$forward_read_file" -irev "$reverse_read_file" -c 1 -t5 -t3

答案2

你的意思是從標題重新命名嗎?

像這樣:

cat a2 | sed -e 's|\(.*\)\(good_\)\(.*\)\(.fastq\)|mv \1\2\3\4 \1\2\4|'
mv SRR5898908_1_prinseq_good_ZsSX.fastq SRR5898908_1_prinseq_good_.fastq
mv SRR5898928_2_prinseq_good_VygO.fastq SRR5898928_2_prinseq_good_.fastq

相關內容