web-dev-qa-db-fra.com

Utilisation de AWK pour traiter les entrées de plusieurs fichiers

De nombreuses personnes ont été très utiles en publiant la solution suivante pour AWK gérer plusieurs fichiers d'entrée à la fois:

$ awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1

Cela fonctionne bien, mais je me demandais si quelqu'un pourrait m'expliquer pourquoi. Je trouvais la syntaxe AWK un peu difficile à comprendre et espérais que quelqu'un ne voudrait pas déranger le fragment de code pour moi.

56
jkovba
awk 'FNR==NR{a[$1]=$2 FS $3;next}

ici, nous traitons la 1ère entrée (fichier2). disons, FS est l'espace, nous construisons un tableau (a) vers le haut, l'index est la colonne1, la valeur est column2 " " column3 le FNR==NR and next _ signifie que cette partie des codes ne fonctionne que pour file2. vous pourriez homme gawk vérifier quels sont NR et FNR

{ print $0, a[$1]}' file2 file1

Quand NR != FNR il est temps de traiter la deuxième entrée, fichier1. ici, nous imprimons la ligne de file1 et prenons column1 comme index, trouvons la valeur dans array (a) print. Dans un autre mot, fichier1 et fichier2 sont joints par colonne1 dans les deux fichiers.

pour NR et FNR, sous peu,

1st input has 5 lines
2nd input has 10 lines,

NR would be 1,2,3...15
FNR would be 1...5 then 1...10

vous voyez l'astuce de FNR==NR vérifier.

64
Kent

J'ai trouvé cette question/réponse sur Google et il semble faire référence à un ensemble de données très spécifique trouvé dans une autre question ( Comment fusionner deux fichiers à l'aide de AWK? ). Ce qui suit est la réponse que je cherchais (et que la plupart des gens pensent, à mon avis), c’est-à-dire, tout simplement pour concaténer chaque ligne de deux fichiers différents en utilisant AWK. Bien que vous puissiez probablement utiliser des utilitaires UNIX tels que rejoindre ou coller , AWK est évidemment beaucoup plus flexible et puissant si votre sortie désirée est différente, en utilisant les déclarations if , ou en modifiant le [ ~ # ~] ofs [~ # ~] (ce qui peut être plus difficile à réaliser en fonction de l’utilitaire; voir ci-dessous), par exemple, modifier le résultat de manière beaucoup plus expressive considération pour les scripteurs Shell.)

Pour une concaténation ligne à ligne simple:

awk 'FNR==NR { a[FNR""] = $0; next } { print a[FNR""], $0 }' file1 file2

Ceci émule la fonction d'un tableau indexé numériquement (AWK n'a que des tableaux associatifs) en utilisant une conversion de type implicite. C'est relativement expressif et facile à comprendre.

Utilisation de deux fichiers appelés test1 et test2 avec les lignes suivantes:

test1:

line one
line two
line three

test2:

line four
line five
line six

J'obtiens ce résultat:

line one line four
line two line five
line three line six

Selon la manière dont vous souhaitez associer les valeurs entre les colonnes de la sortie, vous pouvez choisir le séparateur de champ de sortie approprié. Voici un exemple avec des ellipses (...) séparant les colonnes:

awk 'BEGIN { OFS="..."} FNR==NR { a[(FNR"")] = $0; next } { print a[(FNR"")], $0 }' test1 test2

Cédant ce résultat:

line one...line four
line two...line five
line three...line six

J'espère au moins que cela vous inspire à tirer parti de la puissance de AWK!

11
Amiga500Kid

Il y a quelque temps, je suis tombé sur une très bonne solution pour gérer plusieurs fichiers à la fois. La solution consiste à enregistrer en mémoire les fichiers des matrices AWK à l'aide de la méthode suivante:

FILENAME==ARGV[1] {  file2array[FNR] = $0 ; next }
FILENAME==ARGV[2] {  file1array[FNR] = $0 ; next }

Pour le traitement post-données, il est préférable d’enregistrer le nombre de lignes, ainsi:

FILENAME==ARGV[1] {  file2array[FNR] = $0 ; f2rows = FNR ; next }
FILENAME==ARGV[2] {  file1array[FNR] = $0 ; f1rows = FNR ; next }

f2rows et f1rows tiendra la position de la dernière ligne.

Il contient plus de code, mais si vous souhaitez un traitement des données plus complexe, je pense que c'est la meilleure approche. En outre, les approches précédentes traitaient les entrées séquentiellement. Par conséquent, si vous deviez effectuer des calculs qui dépendaient simultanément des données des deux fichiers, vous ne pourriez pas le faire. Cette approche vous permet de tout faire avec les deux fichiers.

3
tpdsantos