Afortunadamente, no necesitas escribir esto en absoluto. Unix tiene un comando de unión para hacer esto por usted.
join -1 1 -2 1 File1 File2
Aquí está "en acción":
will-hartungs-computer:tmp will$ cat f1
4050 S00001 31228 3286 0
4050 S00012 31227 4251 0
4049 S00001 28342 3021 1
4048 S00001 46578 4210 0
4048 S00113 31221 4250 0
4047 S00122 31225 4249 0
4046 S00344 31322 4000 1
will-hartungs-computer:tmp will$ cat f2
4050 12.1 23.6
4049 14.4 47.8
4048 23.2 43.9
4047 45.5 21.6
will-hartungs-computer:tmp will$ join -1 1 -2 1 f1 f2
4050 S00001 31228 3286 0 12.1 23.6
4050 S00012 31227 4251 0 12.1 23.6
4049 S00001 28342 3021 1 14.4 47.8
4048 S00001 46578 4210 0 23.2 43.9
4048 S00113 31221 4250 0 23.2 43.9
4047 S00122 31225 4249 0 45.5 21.6
will-hartungs-computer:tmp will$
$ awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1
4050 S00001 31228 3286 0 12.1 23.6
4050 S00012 31227 4251 0 12.1 23.6
4049 S00001 28342 3021 1 14.4 47.8
4048 S00001 46578 4210 0 23.2 43.9
4048 S00113 31221 4250 0 23.2 43.9
4047 S00122 31225 4249 0 45.5 21.6
4046 S00344 31322 4000 1
Explicación:(Basado en parte en otra pregunta. Aunque un poco tarde).
FNR
se refiere al número de registro (normalmente el número de línea) en el archivo actual y NR
se refiere al número total de registros. El operador ==es un operador de comparación, que devuelve verdadero cuando los dos operandos circundantes son iguales. Así que FNR==NR{commands}
significa que los comandos dentro de los corchetes solo se ejecutaron mientras se procesaba el primer archivo (file2
ahora).
FS
se refiere al separador de campo y $1
, $2
etc. son los campos 1, 2, etc. de una línea. a[$1]=$2 FS $3
significa que un diccionario(/matriz) (llamado a
) se rellena con $1
tecla y $2 FS $3
valor.
;
separa los comandos
next
significa que cualquier otro comando se ignora para la línea actual. (El procesamiento continúa en la siguiente línea).
$0
es toda la linea
{print $0, a[$1]}
simplemente imprime la línea completa y el valor de a[$1]
(si $1
está en el diccionario, de lo contrario solo $0
está impreso). Ahora solo se ejecuta para el 2do archivo (file1
ahora), debido a FNR==NR{...;next}
.
Debe leer las entradas del archivo 2 en un par de matrices asociativas en el bloque BEGIN. Asumiendo GNU Awk:
BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
En el bloque de procesamiento principal, lee la línea del Archivo 1 y la imprime con los datos correctos de las matrices creadas en el bloque BEGIN:
{ print $0, f[$1], g[$1] }
Suministre el archivo 1 como argumento de nombre de archivo para el programa.
awk 'BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
print $0, f[$1], g[$1] }' "File 1"
Las comillas alrededor del argumento del nombre del archivo son necesarias debido a los espacios en el nombre del archivo. Necesitas las comillas alrededor del getline
nombre de archivo incluso si no contiene espacios, ya que de lo contrario sería un nombre de variable.