2016-12-07 1 views
0

Mit meiner zwei Eingabedatei als: nurDatei Spalte Vergleich und hinge Ausgabe in Perl

file1.txt wie

NP_418770.2 
NP_416485.4 

und file2.txt wie

NP_415931.4: 1-8, 29-40, 69-80, 100-111, 124-132 
NP_418770.2: 264-293 
YP_026226.4: 84-101, 174-182, 208-217, 332-341, 376-388, 593-606 
NP_416485.4: 1-18, 16-25, 106-122, 129-153 
NP_417679.2: 1-10 
NP_417044.4: 1-25, 221-231, 825-836 

zu erhalten die übereinstimmenden ersten Spaltenwerte von Datei1 in Datei2 und Schreiben der Ausgabedatei als (output.txt):

NP_418770.2: 264-293 
NP_416485.4: 1-18, 16-25, 106-122, 129-153 

i verwenden awk-Code als:

file3:

awk -F: "FNR==NR {a[$1]=$0; next}; $1 in a {print a[$1]}" file2.txt file1.txt > output.txt 

jetzt in einer aktualisierten Situation, mit zusätzlich zu obigen Eingaben, i zwei das gleiche Format von file2.txt wie mit mehr Eingabedateien haben. txt

NP_415931.4: 11-88, 59-90, 119-130 
NP_418770.2: 254-283 

und file4.txt

NP_418770.2: 24-29, 33-50 
NP_416485.4: 1-8, 16-22, 26-32, 39-53 

und i alrea dy eine CSV-Datei output.csv als (mit Kopf) haben:

RefSeq_ID,a,b,c,d,e,f,Go_terms(%) 
NP_418770.2,25,83,0,0,0,0,GO:0005887 
NP_416485.4,13,19,8,12,0,0,GO:0016878 GO:0051108 

Nun ist meine Frage, wie ich die Ausgabe aller drei Eingabedateien in die bereits existierenden output.csv anhängen? Die modifizierte Probe output.csv, die ich will für den obigen Fall (erste Zeile ist Header) wäre:

RefSeq_ID,file2_output,file3_output,file4_output,a,b,c,d,e,f,Go_terms 
NP_418770.2,264-293,254-283,24-29; 33-50,25,83,0,0,0,0,GO:0005887 
NP_416485.4,1-18; 16-25; 106-122; 129-153,,1-8; 16-22; 26-32; 39-53,13,19,8,12,0,0,GO:0016878 GO:0051108 

(Beachten Sie, dass die i „“ in file2,3 und 4 Ausgangs zu ändern ‚‘ so also nicht zu stören Format der CSV-Datei)

obwohl ich awk für den vorläufigen Fall, wie kann dies mit einem Perl-Code getan werden?

+0

Warum müssen Sie zu Perl wechseln? – choroba

Antwort

1

Dies erzeugt fast die gewünschte Ausgabe, nur die Reihenfolge der Zeilen wird nicht immer beibehalten.

#!/usr/bin/perl 
use warnings; 
use strict; 
use feature qw{ say }; 

open my $F1, '<', 'file1.txt' or die $!; 
my %f1; 
while (<$F1>) { 
    chomp; 
    $f1{$_} = 1; 
} 

my %output; 
my $count = 1; 
for my $file (qw(file2.txt file3.txt file4.txt)) { 
    open my $F2, '<', $file or die $!; 
    while (<$F2>) { 
     chomp; 
     my @cells = split qr/[,:] /; 
     push @{ $output{ $cells[0] } }, [ @cells[ 1 .. $#cells ] ] 
      if exists $f1{ $cells[0] }; 
    } 
    @$_ != $count and push @$_, [] for values %output; 
    ++$count; 
} 
open my $F2, '<', 'output.csv' or die $!; 
while (<$F2>) { 
    chomp; 
    my ($key, $rest) = split /,/, $_, 2; 
    push @{ $output{$key} }, [$rest] if exists $f1{$key}; 
} 


for my $k (keys %output) { 
    say "$k,", join ',', map { join '; ', @$_ } @{ $output{$k} }; 
} 

es einen Hash von Arrays erzeugt durch die erste Säule verkeilt ist, Werte aus verschiedenen Dateien, in die innere Matrix in der Schleife geschoben werden, werden leere Arrays geschoben Tasten fehlen das doppelte Komma zu erhalten.

+0

ausgezeichnet .. danke –