Respuestas:
La respuesta a continuación se basa en un Q&A similar en SO con algunas modificaciones relevantes:
$ 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
La idea es crear un mapa hash con índice y usarlo como diccionario.
Para la segunda pregunta que hizo en su comentario ( qué se debe cambiar si la segunda columna de file1.txt
será la sexta columna ):
Si el archivo de entrada será como 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
El siguiente comando lo hará:
$ 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
Sé que dijiste awk
, pero hay un join
comando para este propósito ...
{
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
Sería suficiente con el primer join
comando si no fuera por esta línea:
item4 platD
El comando básicamente dice: unirse basado en la segunda columna del primer archivo ( -1 2
), y la primera columna del segundo archivo ( -2 1
), y generar la primera columna del primer archivo y la segunda columna del segundo archivo ( -o 1.1,2.2
). Eso solo muestra las líneas que se emparejaron. El segundo comando de unión dice casi lo mismo, pero dice mostrar las líneas del primer archivo que no se pudieron emparejar ( -v 1
), y mostrar la primera columna del primer archivo y la segunda columna del primer archivo ( -o 1.1,1.2
). Luego clasificamos la salida de ambos combinados. sort -k 1
significa ordenar en base a la primera columna, y sort -k 2
significa ordenar en base a la segunda. Es importante ordenar los archivos según la columna de unión antes de pasarlos join
.
Ahora, escribí la clasificación dos veces, porque no me gusta llenar mis directorios con archivos si puedo evitarlo. Sin embargo, como dijo David Foerster, dependiendo del tamaño de los archivos, es posible que desee ordenar los archivos y guardarlos primero para no tener que esperar para ordenarlos dos veces. Para dar una idea de los tamaños, aquí está el tiempo que toma ordenar 1 millón y 10 millones de líneas en mi computadora:
$ 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
Eso es 1.5 segundos para 1 millón de líneas y 19 segundos para 10 millones de líneas.
%E
en el formato de tiempo) es menos interesante para medir el rendimiento computacional. El tiempo de CPU del modo de usuario ( %U
o simplemente una TIMEFORMAT
variable no establecida) sería mucho más significativo.
%U
.