Antworten:
Die folgende Antwort basiert auf ähnlichen Fragen und Antworten in SO mit einigen relevanten Änderungen:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($2 in dict) ? dict[$2] : $2}1' file2.txt file1.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Die Idee ist, eine Hash-Map mit Index zu erstellen und als Wörterbuch zu verwenden.
Für die zweite Frage, die Sie in Ihrem Kommentar gestellt haben ( was sollte geändert werden, wenn die zweite Spalte von file1.txt
die sechste Spalte ist ):
Wenn die Eingabedatei wie folgt aussehen wird file1b.txt
:
item1 A5 B C D carA
item2 A4 1 2 3 carB
item3 A3 2 3 4 carC
item4 A2 4 5 6 platD
item5 A1 7 8 9 carE
Der folgende Befehl wird es tun:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($6 in dict) ? dict[$6] : $6;$3="";$4="";$5="";$6=""}1' file2.txt file1b.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Ich weiß, dass Sie gesagt haben awk
, aber es gibt einen join
Befehl für diesen Zweck ...
{
join -o 1.1,2.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
join -v 1 -o 1.1,1.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
} | sort -k 1
Mit dem ersten join
Befehl würde es ausreichen, wenn diese Zeile nicht wäre:
item4 platD
Der Befehl lautet im Wesentlichen: Join basierend auf der zweiten Spalte der ersten Datei ( -1 2
) und der ersten Spalte der zweiten Datei ( -2 1
) und Ausgabe der ersten Spalte der ersten Datei und der zweiten Spalte der zweiten Datei ( -o 1.1,2.2
). Das zeigt nur die gepaarten Linien. Der zweite Join-Befehl sagt fast dasselbe aus, zeigt jedoch die Zeilen aus der ersten Datei an, die nicht gepaart werden konnten ( -v 1
), und gibt die erste Spalte der ersten Datei und die zweite Spalte der ersten Datei ( -o 1.1,1.2
) aus. Dann sortieren wir die Ausgabe von beiden kombiniert. sort -k 1
bedeutet sortieren nach der ersten Spalte und sort -k 2
bedeutet sortieren nach der zweiten Spalte . Es ist wichtig, die Dateien nach der Join-Spalte zu sortieren, bevor Sie sie an übergeben join
.
Jetzt habe ich die Sortierung zweimal geschrieben, weil ich meine Verzeichnisse nicht gerne mit Dateien verunreinige, wenn ich helfen kann. Wie David Foerster jedoch sagte, möchten Sie je nach Größe der Dateien die Dateien möglicherweise sortieren und zuerst speichern, um nicht zweimal warten zu müssen. Um eine Vorstellung von den Größen zu bekommen, ist hier die Zeit, die benötigt wird, um 1 Million und 10 Millionen Zeilen auf meinem Computer zu sortieren:
$ ruby -e '(1..1000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 1million.txt
$ ruby -e '(1..10000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 10million.txt
$ head 10million.txt
item530284 plat530284
item7946579 plat7946579
item1521735 plat1521735
item9762844 plat9762844
item2289811 plat2289811
item6878181 plat6878181
item7957075 plat7957075
item2527811 plat2527811
item5940907 plat5940907
item3289494 plat3289494
$ TIMEFORMAT=%E
$ time sort 1million.txt >/dev/null
1.547
$ time sort 10million.txt >/dev/null
19.187
Das sind 1,5 Sekunden für 1 Million Zeilen und 19 Sekunden für 10 Millionen Zeilen.
%E
im Zeitformat) weniger interessant, um die Rechenleistung zu messen. Die CPU-Zeit im Benutzermodus ( %U
oder einfach eine nicht gesetzte TIMEFORMAT
Variable) wäre viel aussagekräftiger.
%U
.