unir filas basadas en una cadena en 2 columnas de 2 archivos

unir filas basadas en una cadena en 2 columnas de 2 archivos

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 awky 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 joincomando 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 1opción se utiliza para que file1se impriman todas las líneas de, incluso si no coinciden con una línea de file2.

Desafortunadamente, joincoloca el campo clave del archivo1 al comienzo de cada registro. Esto se soluciona para awkmover los campos a su orden original, usando una variable llamada tcomo 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.

información relacionada