Verbinden Sie zwei Dateien mit übereinstimmenden Spalten

11

File1.txt

    id                            No
    gi|371443199|gb|JH556661.1| 7907290
    gi|371443198|gb|JH556662.1| 7573913
    gi|371443197|gb|JH556663.1| 7384412
    gi|371440577|gb|JH559283.1| 6931777

File2.txt

 id                              P       R       S
 gi|367088741|gb|AGAJ01056324.1| 5       5       0
 gi|371443198|gb|JH556662.1|     2       2       0
 gi|367090281|gb|AGAJ01054784.1| 4       4       0
 gi|371440577|gb|JH559283.1|     21      19      2

output.txt

 id                              P       R       S  NO
 gi|371443198|gb|JH556662.1|     2       2       0  7573913
 gi|371440577|gb|JH559283.1|     21      19      2  6931777

File1.txt hat zwei Spalten und File2.txt hat vier Spalten. Ich möchte beide Dateien mit einer eindeutigen ID verbinden (Array [1] sollte in beiden Dateien übereinstimmen (file1.txt & file2.txt) und nur eine übereinstimmende ID für die Ausgabe angeben (siehe output.txt).

Ich habe versucht join -v <(sort file1.txt) <(sort file2.txt). Jede Hilfe mit awk oder Join-Befehlen angefordert.

Jack
quelle

Antworten:

18

join funktioniert super:

$ join <(sort File1.txt) <(sort File2.txt) | column -t | tac
 id                           No       P   R   S
 gi|371443198|gb|JH556662.1|  7573913  2   2   0
 gi|371440577|gb|JH559283.1|  6931777  21  19  2

ps. Ist die Reihenfolge der Ausgangsspalten wichtig?

Wenn ja, verwenden Sie:

$ join <(sort 1) <(sort 2) | tac | awk '{print $1,$3,$4,$5,$2}' | column -t
 id                           P   R   S  No
 gi|371443198|gb|JH556662.1|  2   2   0  7573913
 gi|371440577|gb|JH559283.1|  21  19  2  6931777
eilen
quelle
funktioniert super. Spaltenreihenfolge spielt keine Rolle
Jack
Was ist der Grund für die Aufnahme tac?
Michael Mrozek
Das liegt daran, dass die sortHeader-Zeichenfolge am Ende steht. Eigentlich ist es eine schmutzige Lösung. Im Allgemeinen kann der Header in die Mitte der Ausgabe gehen. Hier funktioniert es jedoch.
Eile
10

Ein Weg mit awk:

Inhalt von script.awk:

## Process first file of arguments. Save 'id' as key and 'No' as value
## of a hash.
FNR == NR {
    if ( FNR == 1 ) { 
        header = $2
        next
    }   
    hash[ $1 ] = $2
    next
}

## Process second file of arguments. Print header in first line and for
## the rest check if first field is found in the hash.
FNR < NR {
    if ( $1 in hash || FNR == 1 ) { 
        printf "%s %s\n", $0, ( FNR == 1 ? header : hash[ $1 ] ) 
    }   
}

Führen Sie es wie folgt aus:

awk -f script.awk File1.txt File2.txt | column -t

Mit folgendem Ergebnis:

id                           P   R   S  NO
gi|371443198|gb|JH556662.1|  2   2   0  7573913
gi|371440577|gb|JH559283.1|  21  19  2  6931777
Birei
quelle
+65535 zum Beibehalten der ursprünglichen Zeilenreihenfolge. :-)
zeekvfu
+65535 zum Beibehalten der ursprünglichen Zeilenreihenfolge. :-)
zeekvfu