Odpowiedzi:
Poniższa odpowiedź oparta jest na podobnych pytaniach i odpowiedziach w SO z pewnymi istotnymi modyfikacjami:
$ 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
Pomysł polega na utworzeniu mapy skrótów z indeksem i użyciu jej jako słownika.
W przypadku drugiego pytania zadanego w komentarzu ( co należy zmienić, jeśli druga kolumna file1.txt
będzie szóstą kolumną ):
Jeśli plik wejściowy będzie podobny do 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
Zrobi to następujące polecenie:
$ 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
Wiem, że powiedziałeś awk
, ale join
w tym celu istnieje polecenie ...
{
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
Wystarczyłoby pierwsze join
polecenie, gdyby nie ten wiersz:
item4 platD
Komenda w zasadzie mówi: połącz na podstawie drugiej kolumny pierwszego pliku ( -1 2
) i pierwszej kolumny drugiego pliku ( -2 1
), i wypisz pierwszą kolumnę pierwszego pliku i drugą kolumnę drugiego pliku ( -o 1.1,2.2
). To pokazuje tylko sparowane linie. Drugie polecenie łączenia mówi prawie to samo, ale mówi, aby pokazać wiersze z pierwszego pliku, którego nie można sparować ( -v 1
), i wypisać pierwszą kolumnę pierwszego pliku i drugą kolumnę pierwszego pliku ( -o 1.1,1.2
). Następnie sortujemy dane wyjściowe obu połączonych. sort -k 1
oznacza sortowanie na podstawie pierwszej kolumny i sort -k 2
sortowanie na podstawie drugiej. Ważne jest sortowanie plików na podstawie kolumny łączenia przed przekazaniem ich do join
.
Teraz napisałem sortowanie dwa razy, ponieważ nie lubię zaśmiecać moich katalogów plikami, jeśli mogę pomóc. Jednak, jak powiedział David Foerster, w zależności od rozmiaru plików, możesz posortować pliki i zapisać je najpierw, aby nie musieć czekać na sortowanie dwa razy. Aby dać wyobrażenie o rozmiarach, oto czas potrzebny na posortowanie 1 miliona i 10 milionów linii na moim komputerze:
$ 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
To 1,5 sekundy na 1 milion linii i 19 sekund na 10 milionów linii.
%E
w formacie czasu) jest mniej interesujący do mierzenia wydajności obliczeniowej. Czas procesora w trybie użytkownika ( %U
lub po prostu TIMEFORMAT
zmienna nieuzbrojona ) byłby znacznie bardziej znaczący.
%U
.