for ループを使用して、さまざまなファイルから .extension の前の 4 つのランダムな文字を削除するにはどうすればよいでしょうか?

for ループを使用して、さまざまなファイルから .extension の前の 4 つのランダムな文字を削除するにはどうすればよいでしょうか?

私はバイオインフォマティクスを多用した学部研究プロジェクトに取り組んでおり、ファイル処理のパイプラインを進めています。背景: 私はショットガン メタゲノム データ (DNA サンプルのヌクレオチド) の非常に大きなスウォッチであるショットガン メタゲノム データと、私が収集した情報によるといくつかの修飾子を扱っています。私はすでにパイプラインのいくつかのステップを実行し、ファイルをいくらかトリミングしてクリーンアップし、修飾子をいくつか追加しました。重要なことは、これらの読み取りがほとんどペアエンド読み取りであることです。つまり、2 つのファイルがヌクレオチドを右から左、左から右に読み取ります。

これまでは、基本的に生物学と生態学だけを頭に詰め込んでいたので、コーディングや、物事を行う方法や理由、一般的な慣行や機能などについて、まったく知識がありません。要点はお分かりでしょう。

とはいえ、私は 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 ループの各反復でペアの終了ファイルを呼び出し、次に使用しているモジュールのいくつかの引数とパラメーターを呼び出しました。

私が現在直面している大きな問題は、パイプラインの次のステップでペアになった最終ファイルをペアにする方法が思いつかないことです。拡張子の直前に 4 つのランダムな文字があり、それを予測できないからです。それらには意味のあるデータは含まれていないので、ファイル名からそれらを削除して、これまでどおりに進めるつもりです。

問題のあるファイルの例を以下に示します。問題は文字列の末尾の 4 文字です。これらを削除すれば、通常どおり文字列操作を行うことができます。

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はそれぞれ順方向と逆方向の読み取りなので、文字列操作になります。問題は文字列の末尾の 4 文字です。これらを削除すれば、通常どおり文字列操作を行うことができます。私のメンターは、FIND 関数または CUT 関数を何らかの方法で使用し、検索の戻り値を操作用の変数として使用することを勧めましたが、それでも同じ問題が発生するように感じます。

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。 を使用してcutSRR サンプル ID を抽出し、それをコマンドで使用して一致するファイル findを検索します。の出力は、返される結果の数がわからないため、配列に格納されます。_2find

これは、一致なし (良くない)、正確に 1 つの一致 (良い、これが望ましい)、および 1 つ以上の一致 (これも良くない) という 3 つの結果を処理します。

結果が 1 つしかない場合は、配列から一致するファイルを抽出し、Perl スクリプトで処理します。

結果が 0 個または複数個ある場合は、警告メッセージを stderr に出力し、次のファイル名に進みます。必要に応じて、これらのケースの前に (またはエラーを処理する他のコード)_1を追加できます。; exit 1;;

これにより、先頭の SRR サンプル ID と、順方向または逆方向のペアリング ファイルであることを識別する_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または同様のシェバン行があり、実行可能フラグが で設定されている) である場合は、 $PATH に以下chmod +xを追加するだけです。/home/gomeza/shared/sharm646-2021-02-24-09_22/Softwares/NGSQCToolkit_v2.3.3/Trimming/

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

関連情報