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.