如何使用 for 循環從各種文件中刪除 .extension 之前的四個隨機字元?
我正在從事一個生物資訊學領域的本科研究項目,並且我正在研究文件處理的管道。一些背景知識:我正在使用鳥槍法宏基因組數據,這些數據是非常大的 A、T、G、C 樣本(DNA 樣本中的核苷酸),以及從我收集的一些限定符中。我已經完成了管道的幾個步驟,這些步驟對文件進行了一些修剪和清理,並添加了一些限定符。重要的是這些讀取大多是成對的末端讀取,這意味著兩個文件從右到左和從左到右讀取核苷酸。
在此之前,我基本上只學習生物學和生態學,所以我真的沒有任何關於編碼或如何/為什麼做事情或常見做法/功能等的上下文。你明白了。
也就是說,我自學了 UNIX 中循環和字元串操作的基本知識,使用不同的模組和函式製作了一些在不同文件夾中執行的 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 循環安全地刪除這些字元?或者任何你認為最有效的方法。
謝謝!
嘗試這樣的事情:
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 和將其標識為正向或反向配對文件的 or
_1
。_2
順便說一句,這可以用一個
if; then; else
代替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