2016-07-22 26 views
0

Ich arbeite mit einer Eingabedatei, die Tab-delimitierte Sequenzen enthält. Gruppen von Sequenzen sind durch Zeilenumbrüche getrennt. Die Datei wie folgt aussieht:Wie zählt man die Anzahl der Schlüssel in einem Hash?

TAGC  TAGC  TAGC  HELP 
    TAGC  TAGC  TAGC 
    TAGC  HELP 
    TAGC 

Hier ist der Code ich habe:

use strict; 
    use warnings; 

    open(INFILE, "<", "/path/to/infile.txt") or die $!; 

    my %hash = ( 
      TAGC => 'THIS_EXISTS', 
      GCTA => 'THIS_DOESNT_EXIST', 
    ); 

    while (my $line = <INFILE>){ 
      chomp $line; 
      my $hash; 
      my @elements = split "\t", $line; 
      open my $out, '>', "/path/to/outfile.txt" or die $!; 
      foreach my $sequence(@elements){ 
        if (exists $hash{$sequence}){ 
         print $out ">$sequence\n$hash{$sequence}\n"; 
        } 
        else 
        } 
         $count++; 
         print "Doesn't exist ", $count, "\n"; 
        } 
      } 
    } 

Wie kann ich feststellen, wie viele Sequenzen vorhanden sein, bevor ich drucken? Ich muss diese Informationen in den Namen der Ausgabedatei eingeben.

Idealerweise hätte ich eine Variable, die ich in den Namen der Datei aufnehmen könnte. Leider kann ich nicht einfach den Skalar von @elements verwenden, da einige Sequenzen nicht ausgedruckt werden. Wenn ich versuche, die vorhandenen Schlüssel in ein Array zu schieben und dann den Skalar dieses Arrays zu drucken, bekomme ich immer noch nicht die Ergebnisse, die ich brauche. Hier ist, was ich versucht habe (alle Variablen, die global sein müssen):

open my $out, '>', "/path/to/file.$number.txt" or die $!;  
    foreach my $sequence(@elements){ 
      if (exists $hash{$sequence}){ 
        push(@Array, $hash{$sequence}, "\n"); 
        my $number = @Array; 
        print $out ">$sequence\n$hash{$sequence}\n"; 
      #.... 

Danke für die Hilfe. Schätze es wirklich.

Antwort

2
my $sequences = grep exists $hash{$_}, @elements; 
open my $out, '>', "/path/to/outfile_containing_$sequences.txt" or die $!; 

Im Listenkontext filtert grep eine Liste nach einem Kriterium; Im skalaren Kontext gibt es eine Anzahl von Elementen zurück, die das Kriterium erfüllten.

+0

Das ist großartig. Vielen Dank. – Rob

0

Der einfachste Weg wäre, zu verfolgen, wie viele Tasten Sie in einer Variablen drucken und sobald Ihre Schleife fertig ist, benennen Sie einfach die Datei mit der Zahl, die Sie berechnet haben. Perl verfügt dazu über eine integrierte Funktion. Der Code würde wie folgt sein:

use strict; 
use warnings; 

open(INFILE, "<", "/path/to/infile.txt") or die $!; 

my %hash = ( 
     TAGC => 'THIS_EXISTS', 
     GCTA => 'THIS_DOESNT_EXIST', 
); 
my $ammt; 

while (my $line = <INFILE>){ 
     chomp $line; 
     my $hash; 
     my @elements = split "\t", $line; 
     open my $out, '>', "/path/to/outfile.txt" or die $!; 
     foreach my $sequence(@elements){ 
       if (exists $hash{$sequence}){ 
        print $out ">$sequence\n$hash{$sequence}\n"; 
        $ammt++; 
       } 
       else 
       } 
       print "Doesn't exist ", $count, "\n"; 
       } 
     } 
} 

rename "/path/to/outfile.txt", "/path/to/outfile${ammt}.txt" or die $!; 

Ich entfernte die $count variabel, da es in Ihrem Code nicht deklariert ist (streng würde darüber beschweren). Here's das offizielle Dokument für rename. Da es True oder False zurückgibt, können Sie überprüfen, ob es erfolgreich war oder nicht.

By the way, beachten Sie, dass:

push(@Array, $hash{$sequence}, "\n"); 

wird zwei Speichern von Elementen ($hash{$sequence} und \n), so dass Zahl doppelt so hoch sein würde, wie es sein sollte.