web-dev-qa-db-fra.com

Comment fusionner deux fichiers en utilisant AWK?

Le fichier 1 comporte 5 champs A B C D E, le champ A étant un entier

Le fichier 2 comporte 3 champs A F G

Le nombre de lignes du fichier 1 est beaucoup plus important que celui du fichier 2 (20 ^ 6 à 5000)

Toutes les entrées de A dans le fichier 1 sont apparues dans le champ A du fichier 2

J'aime fusionner les deux fichiers par le champ A et porter F et G

La sortie souhaitée est A B C D E F G

Exemple

Fichier 1

 A     B     C    D    E
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

Fichier 2

A     F    G   
4050 12.1 23.6
4049 14.4 47.8   
4048 23.2 43.9
4047 45.5 21.6

Sortie désirée

A    B      C      D   E F    G
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
31
Tony
$ 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
36
kurumi

Heureusement, vous n'avez pas du tout besoin d'écrire cela. 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$ 
26
Will Hartung

Vous devez lire les entrées du fichier 2 dans une paire de tableaux associatifs dans le bloc BEGIN. En supposant 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 le 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 nom de fichier getline même s'il ne contient aucun espace car il serait autrement un nom de variable.

5
Jonathan Leffler