我有两个关注Fasta文件:
file1.fasta
>0
GAATAGATGTTTCAAATGTACCAATTTCTTTCGATT
>1
GTTAAGTTATATCAAACTAAATATACATACTATAAA
>2
GGGGCTGTGGATAAAGATAATTCCGGGTTCGAATAC
file2.qual
>0
40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40
40 40 40 40 40 40 40 40 15 40 40
>1
40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 20 40 40 40
40 40 40 40 40 40 40 40 40 40 40
>2
40 40 40 40 7 40 40 5 40 40 40 40 40 40 40 40 37 13 31 20 15 40 10 11 4
40 8 3 29 10 19 18 40 19 15 5
请注意每个fasta Headers 的“qual”文件中的换行符 - 标有“>” . 两个文件的文件头数('>')相同 . 数字质量数=序列长度 .
我想要做的是附加这两个文件产生:
GAATAGATGTTTCAAATGTACCAATTTCTTTCGATT 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 15 40 40
GTTAAGTTATATCAAACTAAATATACATACTATAAA 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 20 40 40 40 40 40 40 40 40 40 40 40 40 40 40
GGGGCTGTGGATAAAGATAATTCCGGGTTCGAATAC 40 40 40 40 7 40 40 5 40 40 40 40 40 40 40 40 37 13 31 20 15 40 10 11 4 40 8 3 29 10 19 18 40 19 15 5
但不知怎的,我的代码不能正确地做到这一点?特别是'qual'文件中每个条目的第二行都没有打印出来 .
use strict;
use Data::Dumper;
use Carp;
use File::Basename;
my $fastafile = $ARGV[0] || "reads/2039F.2.fasta";
my $base = basename( $fastafile, ".fasta" );
my $qualfile = "reads/" . $base . ".qual";
print "$qualfile\n";
open SEQ, '<', $fastafile or die $!; #Seq
open PRB, '<', $qualfile or die $!; #quality
while (my $seq = <SEQ>) {
my $qual = <PRB>;
chomp($seq);
chomp($qual);
if ($seq =~ /^>/ || $qual =~ /^>/) {
next;
}
else {
print "$seq\t$qual\n";
}
}
这样做的正确方法是什么?
3 回答
您错过了质量得分的第二行(以及随后的每一行),并且还会错过其他序列行 . 为了这个和代码重用目的,处理FASTA序列的方式是整个条目/记录:
您还可以在第一次替换时轻松捕获FASTA标头 .
问题是你正在并行浏览文件,所以当一行中的行为“>”时,下一行可能不是“>” .
您正在读取数据的方式是成对的,如下所示:
应用循环规则的同一组数据将执行此操作:
因此,您需要将循环逻辑分开或找到使文件匹配的方法 .
这是尝试分离寻求,但我还没有测试过 .
更新
我将上面的代码重新分解为一个函数,它将根据需要从任意文件句柄中读取一个块,它似乎可以根据需要工作 . 注意当然我在这里尝试了一些技巧,我一直想用于实用的东西 .
经过测试的上述代码完全符合您的要求 .
注意那个\我的东西
从根本上说是一样的
除了事实上前者每次创建一个新的标量,保证相同的值不会对一个成功的循环可见;
所以它变得更像:
这是一个不使用perl但是使用普通shell命令的解决方案:
我搜索了多年的粘贴命令(知道“这是一个超级基本的操作,有人 must 已经实现了解决这个问题的东西”) .
第二个命令行首先将所有换行转换为空格,并添加echo命令以向输入添加最终换行符(因为sed将忽略缺少EOL的行),从而将所有输入行连接成一行然后是sed命令再次拆分(可移植性说明:并非所有sed程序都可以使用任意行长度,但GNU sed会这样做) .