web-dev-qa-db-fra.com

Qu'est-ce que "NR == FNR" dans awk?

J'apprends la comparaison de fichiers en utilisant awk.

J'ai trouvé la syntaxe comme ci-dessous,

awk 'NR==FNR{a[$1];next}$1 in a{print $1}' file1 file2

Je ne comprenais pas ce que signifiait la signification de NR==FNR dans ce? Si j'essaye avec FNR==NR alors aussi j'obtiens la même sortie?

Qu'est-ce que ça fait exactement?

51
Amit

Dans awk, FNR fait référence au numéro d'enregistrement (généralement le numéro de ligne) dans le fichier actuel et NR correspond au nombre total d'enregistrements. L'opérateur == est un opérateur de comparaison, qui renvoie la valeur true lorsque les deux opérandes environnants sont égaux.

Cela signifie que la condition NR==FNR n'est vrai que pour le premier fichier, car FNR revient à 1 pour la première ligne de chaque fichier mais NR continue à augmenter.

Ce modèle est généralement utilisé pour effectuer des actions uniquement sur le premier fichier. Le next à l'intérieur du bloc signifie que toutes les commandes supplémentaires sont ignorées et qu'elles ne sont exécutées que sur des fichiers autres que le premier.

La condition FNR==NR compare les deux mêmes opérandes que NR==FNR, alors il se comporte de la même manière.

64
Tom Fenech

Recherchez les clés (premier mot de la ligne) dans le fichier2 qui figurent également dans le fichier1.
Étape 1: remplissez le tableau a avec les premiers mots du fichier 1:

awk '{a[$1];}' file1

Étape 2: Remplissez le tableau a et ignorez le fichier 2 dans la même commande. Pour cela, vérifiez le nombre total d'enregistrements jusqu'à présent avec le numéro du fichier d'entrée actuel.

awk 'NR==FNR{a[$1]}' file1 file2

Étape 3: Ignorez les actions pouvant venir après } lors de l'analyse du fichier 1

awk 'NR==FNR{a[$1];next}' file1 file2 

Étape 4: imprimer la clé de fichier2 si trouvé dans le tableau a

awk 'NR==FNR{a[$1];next} $1 in a{print $1}' file1 file2
52
Walter A

Recherchez NR et FNR dans le manuel de awk, puis demandez-vous quelle est la condition dans laquelle NR==FNR dans l'exemple suivant:

$ cat file1
a
b
c

$ cat file2
d
e

$ awk '{print FILENAME, NR, FNR, $0}' file1 file2
file1 1 1 a
file1 2 2 b
file1 3 3 c
file2 4 1 d
file2 5 2 e
33
Ed Morton

Il y a awk variables intégrées.

NR - Il donne le nombre total d'enregistrements traités.

FNR - Il donne le nombre total d'enregistrements pour chaque fichier d'entrée.

10
sat

En supposant que vous ayez les fichiers a.txt et b.txt avec

cat a.txt
a
b
c
d
1
3
5
cat b.txt
a
1
2
6
7

Gardez à l'esprit que NR et FNR sont des variables intégrées awk. NR - Donne le nombre total d'enregistrements traités. (dans ce cas, à la fois dans a.txt et b.txt) FNR - Donne le nombre total d'enregistrements pour chaque fichier d'entrée (enregistrements dans a.txt ou b.txt)

awk 'NR==FNR{a[$0];}{if($0 in a)print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
a.txt 1 1 a
a.txt 2 2 b
a.txt 3 3 c
a.txt 4 4 d
a.txt 5 5 1
a.txt 6 6 3
a.txt 7 7 5
b.txt 8 1 a
b.txt 9 2 1

ajoutons "next" pour ignorer le premier correspondant à NR == FNR

en b.txt et en a.txt

awk 'NR==FNR{a[$0];next}{if($0 in a)print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
b.txt 8 1 a
b.txt 9 2 1

dans b.txt mais pas dans a.txt

 awk 'NR==FNR{a[$0];next}{if(!($0 in a))print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
b.txt 10 3 2
b.txt 11 4 6
b.txt 12 5 7

awk 'NR==FNR{a[$0];next}!($0 in a)' a.txt b.txt
2
6
7