2012-03-14 5 views
3

シーケンスまたは文字列内のA、C、およびGのカウント数を希望します。私は次のコードを書いています。tr ///演算子を使用して文字列内の文字をカウントする

しかし、私が値を印刷すると、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 

答えて

6
あなた $_ = tr/ $_ =~ tr/に変更

。また、whileの中括弧がありません。

+0

ありがとうございます。それはルーキーミスでした。 – Jordan

1

'C'または'G'が含まれていないため、'5'はありません。あなたはの値を$_から$_に変更しています。 $_ =~ tr//)の操作を$_にバインドすると、必要な結果が得られます。

実際には、コンテキスト変数にをバインドするのに、は必要ありません。バインディングは、正規表現を適用したり、別の変数に演算を変換することができます。あなたが結合演算子、=~代わりの割り当てoperat0rを必要と答え

$_{$_}++ foreach m/[ACG]/g; 
say "A:$_{A}, C:$_{C}, G:$_{G}"; 
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"; 
} 
1

my $a = tr/A//; 
my $c = tr/C//; 
my $g = tr/G//; 

しかし、あなたも、このようにそれを行うことができます:あなたが執筆したほうが良いと思います、=、またはデフォルト変数をバインドする必要はありません。

最近、私は物事のこれらの種類のための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の既定の変数を使用していた場合は、私はさらに$_がぶつかり合ってしまうことに注意してください。私も、実装の詳細を知る必要はありませんので、私は私まで、サブルーチンにそれを移動することができ

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を行うことができます知っているが、それだけではなく、より手間のだが、l4m3 XORの文字列に、おそらくいくつかの巧妙な方法はあり

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///を好きではないが、私は決してきていない場合:追加のサブルーチンコールがビッグデータいじるが遅くなるかもしれないが、evalを取り除くためにどのように把握することができますそれを理解するのに十分長い間それを追い求めました(あなたがすでにやっているものよりも良いとは限りません)。

関連する問題