Unirse, completando los valores clave que faltan

Unirse, completando los valores clave que faltan

Tengo dos archivos que tienen un valor de clave principal como primer campo y un valor correspondiente como los campos restantes, y algunos valores de clave principal faltan en uno de ellos pero están presentes en otro, y viceversa:

$ cat jointest1.txt jointest2.txt  
a 1  
b 2  
d 4  
e 5    

a 10  
b 11  
c 12  
d 13  

Esperaría un resultado que combine esos archivos de acuerdo con una clave principal, ya sea sustituyendo los valores faltantes o no, como:

$ joinmerge  jointest1.txt jointest2.txt   
a 1 10  
b 2 11  
c - 12  
d 4 13  
e 5 -

La capacidad de reemplazar valores faltantes con guiones o algo así es opcional.

Lo intenté join, pero dice que mis archivos no están ordenados correctamente:

$ join jointest1.txt jointest2.txt   
a 1 10  
b 2 11  
join: file 2 is not in sorted order  
d 4 13  

¿Qué comando debería usar en su lugar?

Respuesta1

Pruebe lo siguiente:

> join -e- -a1 -a2 jointest1 -o 0 1.1 1.2 2.1 2.2 jointest2
a a 1 a 10
b b 2 b 11
c - - c 12
d d 4 d 13
e e 5 - -

o

> join -e- -a1 -a2 jointest1 -o 0 1.2 2.2 jointest2
a 1 10
b 2 11
c - 12
d 4 13
e 5 -

No estoy seguro de si/cómo es posible lograr lo mismo sin la opción -o. La opción -o dice: primero imprima el campo de unión, luego el campo no. 2 del archivo 1, luego el campo 2 del archivo 2. Es un poco triste que tengas que conocer el formato de los archivos para que los campos vacíos funcionen.

Respuesta2

¿Qué implementación joinestás usando? Con join (GNU coreutils) 5.97, puedo usar

[0 1021] ~/temp/jointest % join -a1 -a2 jointest1.txt jointest2.txt
a 1 10
b 2 11
c 12
d 4 13
e 5 

y la unión "simple" también funciona (pero omite c y e). Hay una -eopción que supuestamente le permite elegir el marcador para campos vacíos, pero parece estar rota en mi versión y solo llena el caso e, no el caso c.

Respuesta3

Escribí una herramienta Perl exactamente para ese problema de clave y valor:

Emparejar las filas correctas: cualquier número de archivos. También está disponible a través deGitHub.

Para ejecutarlo escribes:

merge -k -e "-" jointest1.txt jointest2.txt

información relacionada