Un script de shell para unir dos archivos

8

Quiero escribir una shell scriptque se produzcan dos archivos Ay B, y conseguir un resultado como este:

Archivo A:

user_a tel_a addr_a
user_b tel_b addr_b

Archivo B:

process_1 user_a
process_2 user_a
process_3 user_b

Y el resultado:

user_a process_1 tel_a addr_a
user_a process_2 tel_a addr_a
user_b process_3 tel_b addr_b

¿Cómo puedo hacer esto? awk¿o algo mas?

Navid Farhadi
fuente
2
Creo que se puede hacer usando cuty pastesolo, pero no entiendo bien el sintaxis.
Bernhard
¡Mis archivos tienen muchos registros y campos, no puedo cortar y pegar! Esto es solo una muestra.
Navid Farhadi
1
@NavidFarhadi no corta y pega: hay dos comandos reales cuty pastemira su página de manual.
Matteo
Puedo cargar ambos archivos en la memoria por completo y también puedo usar awk.
Navid Farhadi
También puedo usar perl u otros, si fueran ejecutables en la línea de comando de Linux.
Navid Farhadi

Respuestas:

15

join ...

join -1 2 -2 1 FileB FileA

Salida

user_a process_1 tel_a addr_a
user_a process_2 tel_a addr_a
user_b process_3 tel_b addr_b

Los archivos de entrada deben ordenarse por el campo clave ... Sus archivos de ejemplo ya están ordenados, por lo que no era necesario, pero de lo contrario podría incorporar el orden de la siguiente manera.

join -1 2 -2 1 <(sort -k2 FileB) <(sort FileA)
Peter.O
fuente
¿Qué significa los parámetros numéricos?
Navid Farhadi
55
@Navid: Siempre puede obtener la mejor y más precisa descripción de los parámetros de un comando consultando el manual , escribiendo man joinen la línea de comando del terminal ... -1 2   -2 1 significa: unirse en el '1er archivo 2do campo' y el ' 2do archivo 1er campo '
Peter.O
3

Dado joiny pasteno están disponibles en todas partes (no están en mi sistema basado en BusyBox, por ejemplo), aquí es cómo hacerlo con awk, conforme a lo solicitado:

awk 'BEGIN {
    while( (getline < "fileA") > 0) A[$1]=$2 OFS $3 # read fileA into the array A
    close("fileA")
  } {
    print $2, $1, A[$2]
  }' fileB
dubiousjim
fuente
Por cierto, te perdiste el separador A[$1]=$2 OFS $3... Aquí hay otra variante que evita el bucle manual en COMENZAR, pero es más o menos lo mismo (para awk ), aunque introduce una prueba de condición innecesaria para el segundo archivo: awk 'NR==FNR {A[$1]=$2 OFS $3;next} {print $2, $1, A[$2]}' fileA fileB... (+ 1)
Peter.O