2017-06-09 2 views
-3

bis Ende der Zeichenfolge habe ich eine Datei mit vielen Zeilen wie diese:Perl-Capture und fügen

ChrVIII_A_nidulans_FGSC_A4 AspGD gene 3861520 3863875 . + . ID=AN0338;Name=AN0338;Gene=CYP680A1;Note=Putative%20cytochrome%20P450;orf_classification=Uncharacterized;Alias=ANIA_00338,ANID_00338 

Meine Region von Interesse ist ;Gene=_____; - das Zeug zwischen den = und ;.

Wenn diese Region existiert, möchte ich sie an das Ende der Linie mit einem, an der Vorderseite angehängt. Wenn es nicht existiert, möchte ich die Zeile trotzdem ausdrucken!

ChrVIII_A_nidulans_FGSC_A4 AspGD gene 3861520 3863875 . + . ID=AN0338;Name=AN0338;Gene=CYP680A1;Note=Putative%20cytochrome%20P450;orf_classification=Uncharacterized;Alias=ANIA_00338,ANID_00338,CYP680A1 

Dies ist, was ich in Perl versucht habe und ich weiß nicht, warum es nicht funktioniert.

use strict; 
use warnings; 
open(SOURCE,"<annotation.gff") or die "Source file not found!\n"; 

my $line1; 
foreach $line1(<SOURCE>)   #iterating over SOURCE file 
{ 
if($line1=~/Gene\=([a-zA-Z0-9\-]+)\;/) 
printf "$line1,$1"; 
} 
else {printf "$line1";} 
} 

Kann mir jemand zeigen, was ich falsch mache?

+1

Der Code, den Sie nicht gepostet nicht wegen einer fehlenden kompilieren {. Veröffentlichen Sie den Code, den Sie tatsächlich verwenden. – toolic

+0

Wenn ich den Kompilierfehler behebe, sehe ich Warnmeldungen. Nicht wahr? – toolic

+0

'chomp' dass $ line1 – toolic

Antwort

3

der durch den Code Lassen Sie los:

use strict; 
use warnings; 

Gut. Jedoch Ihr Code auszuführen versuchen gibt:

syntax error at ss.pl line 9, near ") printf" syntax error at ss.pl line 11, near "else"

, die bedeutet, dass Sie den Code nicht haben schreiben Sie lief, also können wir es nicht wirklich vertrauen. Tu das nicht. Reduzieren Sie Ihr Problem auf ein kleines, eigenständiges Skript, das andere ausführen können.

open(SOURCE,"<annotation.gff") or die "Source file not found!\n"; 
  • Verwenden Bareword Dateihandies nicht wie SOURCE. Verwenden Sie stattdessen lexikalische Dateihandles.

  • Schreiben Sie den Namen der Datei, die Sie öffnen möchten, nicht fest. Dadurch wird es schwierig, den Namen der Datei genau zu übermitteln, deren Programm bei einem Fehler nicht geöffnet werden konnte.

  • Fügen Sie in die Fehlernachricht den tatsächlichen Fehler Ihres Programms ein, anstatt Ihre ungerechtfertigten Annahmen fest zu codieren.

  • Verwenden Sie nicht das Zwei-Argumente-Formular von open, insbesondere wenn Sie die Flexibilität haben möchten, Dateinamen als Befehlszeilenargumente anzugeben, anstatt das Skript bei jeder neuen Eingabedatei bearbeiten zu müssen. Das heißt, verwenden

    my $annotation_file = 'annotation.gff'; 
    open my $source, '<', $annotation_file 
        or die "Failed to open annotation source '$annotation_file': $!"; 
    
  • Sie die Iterationsvariable für eine Schleife außerhalb des Anwendungsbereichs des loop.That ist nicht erklären, statt:

    my $line1; 
    foreach $line1 (...) 
    

    Verwendung

    foreach my $line1 (...) 
    
  • Aber natürlich sollten Sie nicht eine for Schleife verwenden, um über den Inhalt einer Datei zu iterieren, weil dies macht Ihr Programm schlürfen (d.h. Lesen Sie den gesamten Inhalt der Datei in den Speicher als eine Liste von Zeilen.Dadurch hängt der Speicherbedarf Ihres Programms von der Größe der Eingabe und nicht von der Größe der längsten Zeile ab. Lassen Sie auch das 1 Suffix fallen: Sie durchlaufen jede Zeile in der Datei, nicht nur die erste Zeile.

    while (my $line = <$source>) { 
    
  • nicht printf Verwenden Sie, wenn Sie einfach nur Strings drucken. Verwenden Sie statt printf "$line1,$1"print "$line,$1\n".

  • Und das bringt uns zu einem anderen Problem. Wenn Sie die Zeile lesen, entfernen Sie niemals die neue Zeile von ihrem Ende. Daher ist die Zeichenfolge, die Sie drucken, "...\n...", die den Effekt von , der vorangestellt wird, die erfasste Zeichenfolge an dem Anfang der folgenden Zeile erstellt.

Das führt uns zu etwas bringt, das funktioniert:

use strict; 
use warnings; 

my $annotation_file = 'annotation.gff'; 

open my $source, '<', $annotation_file 
    or die "Cannot open annotation source '$annotation_file': $!"; 

while (my $line = <$source>) { 
    if($line =~ /Gene = ([^;]+) ;/x) { 
     chomp $line; 
     print join(',' => $line, $1), "\n"; 
    } 
    else { 
     print $line; 
    } 
} 
0

Try this:

use strict; 
use warnings; 
open(my $fh, '<', 'annotation.gff') or die $!; 

while (<$fh>) { 
    chomp; 
    /Gene=([a-zA-Z0-9\-]+)\;/ and $_ .= ",$1"; 
    print "$_\n"; 
} 

close $fh; 
+0

Die Antwort –

+1

@Sinan Ünür, vielen Dank für Ihre Notiz! –