2016-05-11 14 views
0

Ich bin auf der Suche nach etwas ähnlich dem Bash-Befehl Comm, die ich verwenden kann, um Einträge sowohl für meine 2 Dateien als auch für sie gemeinsam zu wählen. Comm funktionierte gut, wenn ich nur eine Spalte pro Datei hatte, z.BASH Comm-Befehl, aber für mehrere Spalten

comm -13 FILE1.txt FILE2.txt > Entries_only_in_file1.txt 

Aber jetzt habe ich mehrere Spalten von Informationen, die ich behalten möchte. Ich möchte Spalte 2 als diejenige auswählen, die Zeilen für eindeutige und gemeinsame Einträge zwischen meinen beiden Dateien filtern soll. Wenn der Eintrag in Spalte zwei in beiden Dateien erscheint, möchte ich auch die Informationen in den Spalten 3, 4 und 5 (wenn möglich, ist dies nicht so wichtig). Hier ist ein Beispiel für die Eingabe und Ausgabe.

FILE1.txt 
NM_023928 AACS 2 2 1 
NM_182662 AADAT 2 2 1 
NM_153698 AAED1 1 5 3 
NM_001271 AAGAB 2 2 1 


FILE2.txt 
NM_153698 AAED1 2 5 3 
NM_001271 AAGAB 2 2 1 
NM_001605 AARS 3 40 37 
NM_212533 ABCA2 3 4 2 

Ausgang gesucht:

COMMON.txt 
NM_153698 AAED1 1 5 3 2 5 3 
NM_001271 AAGAB 2 2 1 2 2 1 

UNIQUE_TO_1.txt 
NM_023928 AACS 2 2 1 
NM_182662 AADAT 2 2 1 

UNIQUE_TO_2.txt 
NM_001605 AARS 3 40 37 
NM_212533 ABCA2 3 4 2 

Ich weiß, es hat vor ähnliche Fragen, aber ich kann nicht ganz das finden, was ich suche. Irgendwelche Ideen sehr geschätzt, danke.

+1

Werfen Sie einen Blick auf 'join'. Beachten Sie, dass Ihre Eingaben für das verbundene Feld sortiert werden müssen. –

Antwort

0

join hat die folgenden Optionen, die für Ihre Aufgabe nützlich sind:

  • -j FIELD: Werden Sie Mitglied auf dem Feld FIELD
  • -o FORMAT: Ausgabeformat angeben, wie ein Komma Liste der DATEINR.FELD getrennt.
  • -v FILENUM: Ausgangsleitungen nur auf FILENUM.

Gemeinsam ist den beiden Dateien:

$ join -j2 -o 1.1,1.2,1.3,1.4,1.5,2.3,2.4,2.5 FILE1.txt FILE2.txt 
NM_153698 AAED1 1 5 3 2 5 3 
NM_001271 AAGAB 2 2 1 2 2 1 

Einzigartig FILE1:

$ join -j2 -v1 FILE1.txt FILE2.txt 
AACS NM_023928 2 2 1 
AADAT NM_182662 2 2 1 

Einzigartig FILE2:

$ join -j2 -v2 FILE1.txt FILE2.txt 
AARS NM_001605 3 40 37 
ABCA2 NM_212533 3 4 2 
+0

So einfach, aber funktioniert perfekt, danke! – Yano

0

Für Linien gemeinsam mit jedem der Datei können Sie den join Befehl mit sort auf jeder der Dateien verwenden

Ein Auszug aus der man-Seite von join

-v file_number 
     Do not display the default output, but display a line for each 
     unpairable line in file file_number. The options -v 1 and -v 2 
     may be specified at the same time. 

-1 field 
     Join on the field'th field of file1. 

-2 field 
     Join on the field'th field of file2. 

So join auf zwei Dateien mit spezifischen Spalten für Datei 1 erhalten werden von

Das gleiche auf der Datei 2 wird pro

Duce
$ join -v 2 <(sort file1.txt) <(sort file2.txt) 
NM_001605 AARS 3 40 37 
NM_212533 ABCA2 3 4 2 

für den gemeinsamen Teil, nehme an, dass Sie diese Zeilen müssen die Spalte 2 als gleiche haben, Am folgenden Ansatz zu tun. Immer die Spalten gemeinsam in den beiden Dateien und Schreiben in eine Datei file3.txt sagen

$ join <(sort file1.txt) <(sort file2.txt) > file3.txt 
$ cat file3.txt 
NM_001271 AAGAB 2 2 1 AAGAB 2 2 1 
NM_153698 AAED1 1 5 3 AAED1 2 5 3 

Jetzt awk ich mit dem sich wiederholenden Spaltennummer 6 als

$ awk '{$6=""; print $0}' file3.txt 
NM_001271 AAGAB 2 2 1 2 2 1 
NM_153698 AAED1 1 5 3 2 5 3 

, die die Ausgabe erwartet, wie Sie ist ausschließen.

0

Sie, dass mit Gnu awk archieve kann, ist hier ein Skript:

script.awk

function unique(filename, line) { 
    split(line , tmp, FS) 
    print tmp[1], tmpp[2], tmp[3], tmp[4], tmp[5] >> filename 
} 

NR == FNR { # in case we are reading the first file: store line under key 
     file1[ $2 ] = $0 
     next 
    } 

    { 
     if($2 in file1) { # key from file2 was in also in file1: 
      split(file1[ $2 ], tmp, FS) 
      print $1, $2, tmp[3], tmp[4], tmp[5], $3, $4, $5 >> "COMMON.txt" 
    # remove common key, thus we can later find unique keys from file1 
      delete file1[ $2 ] 
     } 
     else { # unique key from file2 
      unique("UNIQUE_TO_2.txt", $0) 
     } 
    } 

END { 
    # remaining keys are unique in file1 
     for(k in file1) { 
      unique("UNIQUE_TO_1.txt", file1[ k ]) 
     } 
    } 

es wie folgt verwendet:

# erase the output files if present 
rm -f COMMON.txt UNIQUE_TO_1.txt UNIQUE_TO_2.txt 
# run script, create the file 
awk -f script.awk FILE1.txt FILE2.txt 
# output the files 
for f in COMMON.txt UNIQUE_TO_1.txt UNIQUE_TO_2.txt; do echo "$f"; cat "$f"; done 

Der printf ... >> filename fügt den Text nach Dateiname. Dies erfordert die rm der Ausgabedateien, wenn das Skript ein zweites Mal ausgeführt wird.