
Tengo un archivo1 con 3 columnas y un archivo2 con 4 columnas en un sistema Linux. ¿Cómo uno los dos archivos según la cadena de la columna 3 del archivo 1 con la cadena de la columna 2 del archivo 2? File2 es una base de datos grande con muchas entradas. Las columnas 3 y 2 de archivo1 y archivo2 respectivamente comparten solo unas pocas cadenas. Me gustaría generar el archivo1 con filas del archivo2 unidas en caso de que las cadenas coincidan y generar un guión para las entradas que no coinciden.
archivo1:
300 100 a101
450 410 a400
670 710 a20
700 610 a340
archivo2:
b30 a340 tttttttt 456
b500 a200 llllllll 567
b60 a101 uuuuuuuu 344
b40 a50 kkkkkkkk 223
producción:
300 100 a101 b60 a101 uuuuuuuu 344
450 410 a400 -
670 710 a20 -
700 610 a340 b30 a340 tttttttt 456
Respuesta1
Usando GNU awk
y GNU join
, que son estándar en Linux (pueden funcionar o no con versiones que no sean GNU):
$ join -a1 -1 3 -2 2 <(sort -k3,3 file1) <(sort -k2,2 file2) |
awk '$4 == "" { $4 = "-" }; {t=$1; $1=$2; $2=$3; $3=t; print}' |
sort
300 100 a101 b60 uuuuuuuu 344
450 410 a400 -
670 710 a20 -
700 610 a340 b30 tttttttt 456
El join
comando une archivo1 y archivo2 en los campos 3 y 2 respectivamente. Usasustitución de procesospara garantizar que ambos archivos estén ordenados por sus respectivos campos clave. La -a 1
opción se utiliza para que file1
se impriman todas las líneas de, incluso si no coinciden con una línea de file2
.
Desafortunadamente, join
coloca el campo clave del archivo1 al comienzo de cada registro. Esto se soluciona para awk
mover los campos a su orden original, usando una variable llamada t
como titular temporal para el valor de $1. El script awk también agrega el carácter de guión final en el campo $4 si no hay coincidencia entre los archivos (porque join
él mismo no hace esto).
Finalmente, se ordena la salida.