Risposte:
La risposta di seguito si basa su domande e risposte simili in SO con alcune modifiche rilevanti:
$ 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
L'idea è di creare una mappa hash con indice e usarla come dizionario.
Per la seconda domanda che hai posto nel tuo commento ( cosa dovrebbe essere cambiato se la seconda colonna file1.txt
sarà la sesta colonna ):
Se il file di input sarà simile 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
Il seguente comando lo farà:
$ 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
So che hai detto awk
, ma join
a questo scopo esiste un comando ...
{
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
Sarebbe sufficiente con il primo join
comando se non fosse per questa riga:
item4 platD
Il comando dice sostanzialmente: join basato sulla seconda colonna del primo file ( -1 2
) e sulla prima colonna del secondo file ( -2 1
), e genera la prima colonna del primo file e la seconda colonna del secondo file ( -o 1.1,2.2
). Ciò mostra solo le linee accoppiate. Il secondo comando join dice quasi la stessa cosa, ma dice di mostrare le righe del primo file che non possono essere accoppiate ( -v 1
) e di generare la prima colonna del primo file e la seconda colonna del primo file ( -o 1.1,1.2
). Quindi ordiniamo l'output di entrambi combinati. sort -k 1
significa ordinare in base alla prima colonna e sort -k 2
significa ordinare in base alla seconda. È importante ordinare i file in base alla colonna di join prima di passarli a join
.
Ora, ho scritto l'ordinamento due volte, perché non mi piace sporcare le mie directory di file se posso aiutarlo. Tuttavia, come ha detto David Foerster, a seconda della dimensione dei file, potresti voler ordinare i file e salvarli prima di non aspettare di ordinarli due volte. Per dare un'idea delle dimensioni, ecco il tempo necessario per ordinare 1 milione e 10 milioni di righe sul mio computer:
$ 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
Sono 1,5 secondi per 1 milione di linee e 19 secondi per 10 milioni di linee.
%E
nel formato temporale) è meno interessante per misurare le prestazioni computazionali. Il tempo della CPU in modalità utente ( %U
o semplicemente una TIMEFORMAT
variabile non impostata ) sarebbe molto più significativo.
%U
.