GNU/Linux >> Tutoriels Linux >  >> Linux

Comment fusionner deux fichiers avec AWK ?

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.


Linux
  1. Comment télécharger des fichiers à l'aide du gestionnaire de fichiers dans Cpanel

  2. Comment créer des fichiers Linux Proc dans le programme C à l'aide de LKM

  3. Fusionner manuellement deux fichiers à l'aide de diff

  4. Fusionner deux fichiers HTML dans le fichier HTML maître

  5. Comment joindre/fusionner plusieurs fichiers mp3 ?

Comment supprimer des lignes vides dans des fichiers à l'aide de Grep, Sed et Awk

Comment comparer des fichiers sous Linux à l'aide de l'outil Meld (Diff/Merge)

Comment :une introduction à l'utilisation de Git

Transférer des fichiers à l'aide de WinSCP

Comment protéger les fichiers par mot de passe à l'aide de l'éditeur Vim dans Ubuntu

Comment compresser un fichier sous Linux