如何使用 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

相关内容