Find

如何使用 for 循環從各種文件中刪除 .extension 之前的四個隨機字元?

  • May 30, 2021

我正在從事一個生物資訊學領域的本科研究項目,並且我正在研究文件處理的管道。一些背景知識:我正在使用鳥槍法宏基因組數據,這些數據是非常大的 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 是樣本,12分別是正向和反向讀取,因此是我的字元串操作。問題是字元串末尾的四個字元。如果我擺脫了這些,我可以像往常一樣進行字元串操作。我的導師建議我以某種方式使用 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

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