Ersetzen übereinstimmender Einträge in einer Spalte einer Datei durch eine andere Spalte aus einer anderen Datei


8

Ich habe zwei durch Tabulatoren getrennte Dateien, die wie folgt aussehen:

Datei1:

NC_008146.1     WP_011558474.1  1155234 1156286 44173
NC_008146.1     WP_011558475.1  1156298 1156807 12
NC_008146.1     WP_011558476.1  1156804 1157820 -3
NC_008705.1     WP_011558474.1  1159543 1160595 42748
NC_008705.1     WP_011558475.1  1160607 1161116 12
NC_008705.1     WP_011558476.1  1161113 1162129 -3
NC_009077.1     WP_011559727.1  2481079 2481633 8
NC_009077.1     WP_011854835.1  1163068 1164120 42559
NC_009077.1     WP_011854836.1  1164127 1164636 7

Datei2:

NC_008146.1     GCF_000014165.1_ASM1416v1_protein.faa
NC_008705.1     GCF_000015405.1_ASM1540v1_protein.faa
NC_009077.1     GCF_000016005.1_ASM1600v1_protein.faa

Ich möchte Spalte 1 von Datei1 mit Datei2 abgleichen und sich durch den entsprechenden Eintrag für Spalte 2 von Datei 2 ersetzen. Die Ausgabe würde folgendermaßen aussehen:

GCF_000014165.1_ASM1416v1_protein.faa     WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa     WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854836.1  1164127 1164636 7

Anscheinend interessieren Sie sich auch für unsere Schwesterseite: Bioinformatik .
Terdon

Danke für den Link @terdon!
BhushanDhamale

Antworten:


14

Sie können dies sehr einfach tun mit awk:

$ awk 'NR==FNR{a[$1]=$2; next}{$1=a[$1]; print}' file2 file1
GCF_000014165.1_ASM1416v1_protein.faa WP_011558474.1 1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa WP_011558475.1 1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa WP_011558476.1 1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa WP_011558474.1 1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa WP_011558475.1 1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa WP_011558476.1 1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa WP_011559727.1 2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa WP_011854835.1 1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa WP_011854836.1 1164127 1164636 7

Oder, da dies wie eine durch Tabulatoren getrennte Datei aussieht:

$ awk -vOFS="\t" 'NR==FNR{a[$1]=$2; next}{$1=a[$1]; print}' file2 file1
GCF_000014165.1_ASM1416v1_protein.faa   WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa   WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa   WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa   WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa   WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa   WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa   WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa   WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa   WP_011854836.1  1164127 1164636 7

Dies setzt voraus, dass jede RefSeq ( NC_*) - ID in file1einen entsprechenden Eintrag in hat file2.

Erläuterung

  • NR==FNR: NR ist die aktuelle Zeilennummer, FNR ist die Zeilennummer der aktuellen Datei. Die beiden sind nur identisch, während die erste Datei (hier file2) gelesen wird.
  • a[$1]=$2; next: Wenn dies die erste Datei ist (siehe oben), speichern Sie das 2. Feld in einem Array, dessen Schlüssel das 1. Feld ist. Fahren Sie dann mit der nextZeile fort. Dies stellt sicher, dass der nächste Block nicht für die 1. Datei ausgeführt wird.
  • {$1=a[$1]; print}: Setzen Sie nun in der zweiten Datei das erste Feld auf den Wert, der im Array afür das erste Feld gespeichert wurde (also den zugehörigen Wert von file2), und drucken Sie die resultierende Zeile.

1
NR == FNRfunktioniert nicht richtig, wenn die erste Datei leer ist. Siehe dies und die zugehörige Antwort für eine
Problemumgehung

3
@iruvar nichts wird gut funktionieren, wenn die erste Datei leer ist, also verstehe ich nicht wirklich, warum das relevant ist. Hier geht es darum, die Daten aus den beiden Dateien zu kombinieren. Wenn eine der Dateien leer ist, ist die gesamte Übung sinnlos.
Terdon

Entschuldigung, ich hätte in diesem speziellen Fall sagen sollen file2und ist nicht file1leer. Ein vernünftiges Verhalten, wenn file2es leer ist, besteht darin, den Inhalt von zu melden file1. Das Problem mit NR == FNRist, dass der damit verbundene Code auf dem Inhalt von file1wann ausgeführt file2wird leer ist
iruvar

3
@iruvar Es gibt hier kein vernünftiges Verhalten, wenn eine der Dateien leer ist. Das sage ich :) Es ist also sinnlos, zu versuchen, diesen Fall anmutig zu behandeln. Und in jedem Fall wird nichts gedruckt, wenn eine der Dateien hier leer ist. Was eigentlich der vernünftigste Ansatz ist, ich würde lieber keine Daten als falsche Daten erhalten.
Terdon

17

Keine Notwendigkeit für awk, vorausgesetzt, die Dateien sind sortiert, können Sie coreutils join verwenden:

join -o '2.2 1.2 1.3 1.4 1.5' file1 file2

Ausgabe:

GCF_000014165.1_ASM1416v1_protein.faa     WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa     WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854836.1  1164127 1164636 7

Wenn Ihre Dateien nicht sortiert sind, können Sie sie entweder zuerst sortieren ( sort file1 > file1.sorted; sort file2 > file2.sorted) und dann den obigen Befehl verwenden. Wenn Ihre Shell das <()Konstrukt unterstützt (bash tut dies), können Sie Folgendes tun:

join -o '2.2 1.2 1.3 1.4 1.5' <(sort file1) <(sort file2)

0

Getestet mit dem folgenden Befehl und hat gut funktioniert

for i in `awk '{print $1}' f2`; do k=`awk -v i="$i" '$1==i {print $2}' f2`;sed  "/$i/s/$i/$k/g" f1 >f3;done

Ausgabe

for i in `awk '{print $1}' f2`; do k=`awk -v i="$i" '$1==i {print $2}' f2`;sed  "/$i/s/$i/$k/g" f1 >f3;done


GCF_000014165.1_ASM1416v1_protein.faa     WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa     WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854836.1  1164127 1164636 7
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.