Heureusement, vous n'avez pas du tout besoin d'écrire ceci. Unix a une commande join pour le faire pour vous.
join -1 1 -2 1 File1 File2
Le voici "en action":
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
Explication :(En partie basée sur une autre question. Un peu tardive cependant.)
FNR
fait référence au numéro d'enregistrement (généralement le numéro de ligne) dans le fichier actuel et NR
fait référence au nombre total d'enregistrements. L'opérateur ==est un opérateur de comparaison, qui renvoie vrai lorsque les deux opérandes environnants sont égaux. Alors FNR==NR{commands}
signifie que les commandes entre parenthèses ne s'exécutent que lors du traitement du premier fichier (file2
maintenant).
FS
fait référence au séparateur de champs et $1
, $2
etc. sont les 1er, 2ème etc. champs sur une ligne. a[$1]=$2 FS $3
signifie qu'un dictionnaire (/array) (nommé a
) est rempli avec $1
clé et $2 FS $3
valeur.
;
sépare les commandes
next
signifie que toutes les autres commandes sont ignorées pour la ligne courante. (Le traitement continue sur la ligne suivante.)
$0
est la ligne entière
{print $0, a[$1]}
imprime simplement toute la ligne et la valeur de a[$1]
(si $1
est dans le dictionnaire, sinon seulement $0
est imprimé). Maintenant, il n'est exécuté que pour le 2ème fichier (file1
maintenant), à cause de FNR==NR{...;next}
.
Vous devez lire les entrées du fichier 2 dans une paire de tableaux associatifs dans le bloc BEGIN. En supposant que GNU Awk :
BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
Dans le bloc de traitement principal, vous lisez la ligne du fichier 1 et l'imprimez avec les données correctes des tableaux créés dans le bloc BEGIN :
{ print $0, f[$1], g[$1] }
Fournissez Fichier 1 comme argument de nom de fichier au programme.
awk 'BEGIN { while (getline < "File 2") { f[$1] = $2; g[$1] = $3 } }
print $0, f[$1], g[$1] }' "File 1"
Les guillemets autour de l'argument du nom de fichier sont nécessaires en raison des espaces dans le nom de fichier. Vous avez besoin des guillemets autour du getline
nom de fichier même s'il ne contient pas d'espaces car il s'agirait autrement d'un nom de variable.