我想在序列或字符串中计算A,C和G的数量。我写了以下代码。
但是当我打印这些值时,只有A打印出来。 C和G显示为零。 在下面的代码中我首先评估A,但是如果我通过首先评估C来切换顺序,我得到C的值,但是现在A和G被打印为零。
有谁能告诉我我的代码有什么问题?谢谢!
#! /usr/bin/perl
use strict;
use warnings;
open(IN, "200BP_junctions_fasta.faa") or die "Cannot open the file: $!\n";
while(<IN>)
next if $_ =~ /\>/;
my $a = ($_ = tr/A//);
my $c = ($_ = tr/C//);
my $g = ($_ = tr/G//);
print "A:$a, C:$c, G:$g\n";
}
该文件如下所示:
> A_Seq ATGCTAGCTAGCTAGCTAGTC > B_Seq ATGCGATCGATCGATCGATAG
答案 0 :(得分:6)
将您的$_ = tr/
更改为$_ =~ tr/
。此外,您错过了while
的开放式大括号。
答案 1 :(得分:1)
因为'5'
中没有'C'
或'G'
s。您分配 $_
到$_
的翻译价值。如果绑定($_ =~ tr//
)操作$_
,您将获得所需的结果。
但是你真的不需要绑定到上下文变量。绑定是为了将正则表达式或转换操作应用于另一个变量。你写得更好:
my $a = tr/A//;
my $c = tr/C//;
my $g = tr/G//;
但你也可以这样做:
$_{$_}++ foreach m/[ACG]/g;
say "A:$_{A}, C:$_{C}, G:$_{G}";
答案 2 :(得分:1)
答案是您需要绑定运算符=~
而不是赋值operat0r,=
,或者您不需要绑定默认变量。
最近,我一直在使用printf
来做这些事情:
while( <DATA> ) {
next if /\>/;
printf "A:%s C:%s G:%s\n", tr/A//, tr/C//, tr/G//;
}
我经常希望tr///
可以插值,所以我可以写这个,这不起作用:
while( my $line = <DATA> ) {
next if $line =~ /\>/;
print "Line is $_\n";
printf "A:%s C:%s G:%s\n", map { $line =~ tr/$_// } qw(A C G);
}
请注意,如果我在$_
中使用了默认变量,我会对碰撞while
产生额外的烦恼。我知道我可以做一个eval
,但这不仅仅是一个麻烦,而是l4m3:
while( my $line = <DATA> ) {
next if $line =~ /\>/;
print "Line is $_\n";
printf "A:%s C:%s G:%s\n", map { eval "\$line =~ tr/$_//" } qw(A C G);
}
我不应该知道实现细节,所以我可以把它移到一个子程序,直到我能弄清楚如何摆脱eval
,虽然额外的子程序调用可能会减慢大数据改写(munging):
while( my $line = <DATA> ) {
next if $line =~ /\>/;
print "Line is $line\n";
printf "A:%s C:%s G:%s\n", map { count_bases( $line, $_ ) } qw(A C G);
}
sub count_bases { eval "\$_[0] =~ tr/$_[1]//" }
如果你不喜欢tr///
,可能有一些巧妙的XOR字符串方法,但我从来没有追求它足够长的时间来解决它(不是说它会比你已经做的更好)
答案 3 :(得分:0)
open(IN, "input") or die "Cannot open the file: $!\n";
while(<IN>) {
next if $_ =~ /\>/;
my $a = @{[m/(A)/g]};
my $c = @{[m/(C)/g]};
my $g = @{[m/(D)/g]};
print "A:$a, C:$c, G:$g\n";
}