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
Antworten:
Sie können dies sehr einfach tun mit
awk
:Oder, da dies wie eine durch Tabulatoren getrennte Datei aussieht:
Dies setzt voraus, dass jede RefSeq (
NC_*
) - ID infile1
einen entsprechenden Eintrag in hatfile2
.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 (hierfile2
) 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 dernext
Zeile 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 Arraya
für das erste Feld gespeichert wurde (also den zugehörigen Wert vonfile2
), und drucken Sie die resultierende Zeile.quelle
NR == FNR
funktioniert nicht richtig, wenn die erste Datei leer ist. Siehe dies und die zugehörige Antwort für einefile2
und ist nichtfile1
leer. Ein vernünftiges Verhalten, wennfile2
es leer ist, besteht darin, den Inhalt von zu meldenfile1
. Das Problem mitNR == FNR
ist, dass der damit verbundene Code auf dem Inhalt vonfile1
wann ausgeführtfile2
wird leer istKeine Notwendigkeit für awk, vorausgesetzt, die Dateien sind sortiert, können Sie coreutils join verwenden:
Ausgabe:
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:quelle
Getestet mit dem folgenden Befehl und hat gut funktioniert
Ausgabe
quelle