Per fortuna, non è affatto necessario scriverlo. Unix ha un comando join per farlo per te.
join -1 1 -2 1 File1 File2
Eccolo "in azione":
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
Spiegazione:(In parte basata su un'altra domanda. Un po' in ritardo però.)
FNR
si riferisce al numero di record (tipicamente il numero di riga) nel file corrente e NR
si riferisce al numero totale di record. L'operatore ==è un operatore di confronto, che restituisce vero quando i due operandi circostanti sono uguali. Quindi FNR==NR{commands}
significa che i comandi tra parentesi vengono eseguiti solo durante l'elaborazione del primo file (file2
adesso).
FS
si riferisce al separatore di campo e $1
, $2
etc. sono i campi 1st, 2nd etc. in una riga. a[$1]=$2 FS $3
significa che un dizionario(/array) (denominato a
) viene riempito con $1
chiave e $2 FS $3
valore.
;
separa i comandi
next
significa che qualsiasi altro comando viene ignorato per la riga corrente. (L'elaborazione continua nella riga successiva.)
$0
è l'intera linea
{print $0, a[$1]}
stampa semplicemente l'intera riga e il valore di a[$1]
(se $1
è nel dizionario, altrimenti solo $0
viene stampato). Ora viene eseguito solo per il secondo file (file1
ora), a causa di FNR==NR{...;next}
.
Devi leggere le voci dal File 2 in una coppia di array associativi nel blocco BEGIN. Supponendo che GNU Awk:
BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
Nel blocco di elaborazione principale, leggi la riga dal File 1 e stampala con i dati corretti dagli array creati nel blocco BEGIN:
{ print $0, f[$1], g[$1] }
Fornisci File 1 come argomento del nome file al programma.
awk 'BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
print $0, f[$1], g[$1] }' "File 1"
Le virgolette attorno all'argomento del nome del file sono necessarie a causa degli spazi nel nome del file. Hai bisogno delle virgolette intorno al getline
filename anche se non conteneva spazi poiché sarebbe altrimenti un nome di variabile.