2016-06-06 14 views
2

Wie kann ich ein Datensatztrennzeichen verwenden und dann gleichzeitig ein Trennzeichen für untergeordnete Datensätze verwenden? Vielleicht ist das nicht der beste Weg, darüber nachzudenken, was ich zu tun versuche. Hier ist mein Ziel:Datensatztrennzeichen in einem Datensatztrennzeichen

Ich möchte eine while-Schleife auf einem einzelnen Tab abgegrenzten Element zu einer Zeit, in einer bestimmten Reihe von Elementen. Für jede Zeile (Zeile) von tabulatorgetrennten Elementen muss ich die Ergebnisse aller while-Schleifen in eine eindeutige Datei drucken. Lassen Sie die folgenden Beispiele zur Klärung beitragen.

Meine Eingabedatei wird ungefähr wie folgt aussehen.

#!/usr/bin/perl 
    use warnings; 
    use strict; 

    open(INFILE, "<", "Clustered_Barcodes.txt") or die $!; 

    my %hash = (
      "TTTATGC" => "TATAGCGCTTTATGCTAGCTAGC", 
      "TTTATGG" => "TAGCTAGCTTTATGGGCTAGCTA", 
      "TTTATCC" => "GCTAGCTATTTATCCGCTAGCTA", 
      "TTTATCG" => "TAGCTAGCTTTATCGCGTACGTA", 
      "TTTATAA" => "TAGCTAGCTTTATAATAGCTAGC", 
      "TTTATAA" => "ATCGATCGTTTATAACGATCGAT", 
      "TTTATAT" => "TCGATCGATTTATATTAGCTAGC", 
      "TTTATAT" => "TAGCTAGCTTTATATGCTAGCTA", 
      "TTTATTA" => "GCTAGCTATTTATTATAGCTAGC", 
      "CTTGTAA" => "ATCGATCGCTTGTAACGATTAGC", 
    ); 

    while(<INFILE>) { 
      $/ = "\n"; 
      my @lines = <INFILE>; 
      open my $out, '>', "Clustered_Barcode_$..fasta" or die $!; 
      foreach my $sequence (@lines){ 
        if (exists $hash{$sequence}){ 
        print $out ">$sequence\n$hash{$sequence}\n"; 
        } 
      } 
    } 

Meine gewünschte Ausgabe drei verschiedene Dateien wäre: Es wird "Clustered_Barcodes.txt"

TTTATGC TTTATGG TTTATCC TTTATCG 
    TTTATAA TTTATAA TTTATAT TTTATAT TTTATTA 
    CTTGTAA 

Mein Perl-Code sieht wie folgt genannt. Die erste Datei „Clustered_Barcode_1.fasta“ genannt werden und wird wie folgt aussehen:

>TTTATGC 
    TATAGCGCTTTATGCTAGCTAGC 
    >TTTATGG 
    TAGCTAGCTTTATGGGCTAGCTA 
    >TTTATCC 
    GCTAGCTATTTATCCGCTAGCTA 
    >TTTATCG 
    TAGCTAGCTTTATCGCGTACGTA 

Beachten Sie, dass diese so formatiert ist, dass die Schlüssel von einer Karotte voraus sind, und dann in der nächsten Zeile ist die längere Sequenz zugeordnet (Wert). Diese Datei enthält alle Sequenzen in der ersten Zeile des Clustered_Barcodes.txt

Meine dritte Datei sollte „Clustered_Barcode_3.fasta“ genannt werden und wie folgt aussehen:

>CTTGTAA 
    ATCGATCGCTTGTAACGATTAGC 

Wenn ich meinen Code ausführen, ist es nur nimmt die zweite und dritte Sequenzzeile in der Eingabedatei. Wie kann ich mit der ersten Zeile beginnen (indem Sie die \ n Anforderung für ein Datensatztrennzeichen entfernen)? Wie kann ich dann jeden Artikel auf einmal bearbeiten und dann die Ergebnisse der Zeile in eine Datei drucken? Auch wenn es eine Möglichkeit gibt, die Anzahl der Sequenzen in den Dateinamen zu integrieren, wäre das großartig. Es würde mir helfen, die Dateien später nach Größe zu organisieren. Zum Beispiel könnte der Name etwas wie "Clusterd_Barcodes_1_File_3_Sequences.fasta" sein.

Danke euch allen.

Antwort

2

Es gibt keine Notwendigkeit zu lesen in der ganzen Datei, die ich hier sehe. Sie müssen nur den Inhalt jeder Zeile durchlaufen:

while(my $line = <INFILE>) { 
     chomp $line; 
     open my $out, '>', "Clustered_Barcode_$..fasta" or die $!; 
     foreach my $sequence (split /\t/, $line){ 
      if (exists $hash{$sequence}){ 
       print $out ">$sequence\n$hash{$sequence}\n"; 
      } 
     } 
    } 
+0

Gibt es eine Möglichkeit, dies zu ändern, so dass der Name der Ausgabedatei die Anzahl der Zeilen in der Datei enthält? Zum Beispiel wären in der Ausgabedatei "Clustered_Barcode_3_2_rows.fasta" nur 2 Zeilen und in der Ausgabedatei "Clustered_Barcode_2_4_rows.fasta" wären 4 Zeilen vorhanden. Vielen Dank, – Rob

3

OK, hier ist so eine Art und Weise, es zu tun:

#!/usr/bin/perl 
use strict; 
use warnings; 

Standard-Präambel.

my %hash = (
    "TTTATGC" => "TATAGCGCTTTATGCTAGCTAGC", 
    "TTTATGG" => "TAGCTAGCTTTATGGGCTAGCTA", 
    "TTTATCC" => "GCTAGCTATTTATCCGCTAGCTA", 
    "TTTATCG" => "TAGCTAGCTTTATCGCGTACGTA", 
    "TTTATAA" => "TAGCTAGCTTTATAATAGCTAGC", 
    "TTTATAA" => "ATCGATCGTTTATAACGATCGAT", 
    "TTTATAT" => "TCGATCGATTTATATTAGCTAGC", 
    "TTTATAT" => "TAGCTAGCTTTATATGCTAGCTA", 
    "TTTATTA" => "GCTAGCTATTTATTATAGCTAGC", 
    "CTTGTAA" => "ATCGATCGCTTGTAACGATTAGC", 
); 

Richten Sie den Hash der Sequenzen ein.

my $infile = 'Clustered_Barcodes.txt'; 
open my $infh, '<', $infile or die "$0: $infile: $!\n"; 

Datei zum Lesen öffnen.

chomp(my @rows = readline $infh); 
my $row_count = @rows; 

Schlitzen Sie alle Zeilen in den Speicher, um die Anzahl der Sequenzen zu erhalten. Wenn Sie zu viele Sequenzen haben, wird dieser Ansatz nicht funktionieren (weil Ihnen der Arbeitsspeicher ausgehen wird (aber das hängt davon ab, wie viel Arbeitsspeicher Sie haben)).

my $i = 1; 
for my $row (@rows) { 

Schleife über die Linien.

my @fields = split /\t/, $row; 

Teilen Sie jede Zeile in durch Tabulatoren getrennte Felder auf.

my $outfile = "Clustered_Barcodes_${i}_File_${row_count}_Sequences.fasta"; 
    $i++; 
    open my $outfh, '>', $outfile or die "$0: $outfile: $!\n"; 

Aktuelle Ausgabedatei öffnen und Zähler inkrementieren.

for my $field (@fields) { 
     print $outfh ">$field\n$hash{$field}\n" if exists $hash{$field}; 
    } 

Schreiben Sie jedes Feld (und seine Zuordnung) in die Ausgabedatei.

} 

Und wir sind fertig. Der Hauptunterschied zu Ihrem ursprünglichen Code besteht in der Verwendung von split /\t/ und foreach, um Felder innerhalb einer Zeile zu durchlaufen.


Wir können es tun, ohne Schlürfen auch:

while (my $row = readline $infh) { 
    chomp $row; 

Schleife über die Zeilen, eins nach dem anderen. Dies ersetzt die 4 Zeilen von chomp(my @rows = readline $infh); bis for my $row (@rows) {.

Aber jetzt haben wir die $i und $row_count Variablen verloren, so müssen wir die Initialisierung von $outfile ändern:

my $outfile = "Clustered_Barcodes_$..fasta"; 

, dass die Änderungen alle notwendigen sein sollte. (Sie können $row_count zurück in diesem Szenario erhalten, indem $infh zweimal (das erste Mal nur zum Zählen lese, dann seek ing zum Start zurück), dies ist für den Leser als Übung.)

+0

Das ist großartig. Vielen Dank für die Antwort. Was das Schlürfen betrifft, werde ich Tausende von Textzeilen in den Code eingeben. Ich werde dies über einen Server tun und könnte genug RAM haben, aber ich könnte nicht, abhängig von meinem Datensatz. Gibt es eine speichereffiziente Alternative zum Schlürfen? Auch hier bin ich sehr dankbar für Ihr Fachwissen. Vielen Dank. – Rob

+0

@Rob Ich habe meine Antwort aktualisiert. – melpomene