awk: forcer un statut de retour?

17

Ceci fait suite à ma question précédente .

Je valide le nombre de champs dans / etc / passwd à l'aide de cet extrait pratique. Dans l'exemple suivant, les utilisateurs 'fieldcount1' et 'fieldcount2' ont le mauvais nombre de champs:

$ awk -F: ' NF!=7 {print}' /etc/passwd
fieldcount1:x:1000:100:fieldcount1:/home/fieldcount1:/bin/bash::::
fieldcount2:blah::blah:1002:100:fieldcount2:/home/fieldcount2:/bin/bash:
$ echo $?
0

Comme vous le remarquerez, awk se terminera avec un état de retour de 0. De son point de vue, il n'y a aucun problème ici.

Je voudrais incorporer cette déclaration awk dans un script shell. Je voudrais imprimer toutes les lignes qui sont des erreurs et définir le code de retour sur 1 (erreur).

Je peux essayer de forcer un statut de sortie particulier, mais awk n'imprime qu'une seule ligne:

$ awk -F: ' NF!=7 {print ; exit 1}' /etc/passwd
fieldcount1:x:1000:100:fieldcount1:/home/fieldcount1:/bin/bash::::
$ echo $?
1

Puis-je forcer awk à quitter avec un état de retour de «1» et imprimer toutes les lignes qui correspondent?

Stefan Lasiewski
la source

Réponses:

23

Conservez le statut dans une variable et utilisez-le dans un ENDbloc.

awk -F: 'NF != 7 {print; err = 1}
         END {exit err}' /etc/passwd
geekosaure
la source
Très bien. Cependant, je rencontre des problèmes pour l'incorporer dans un script bash. J'essaie de capturer le statut de retour de cette déclaration awk en ajoutant quelque chose comme ; echo $?après cette déclaration awk. Toutefois, il echo $?n'est jamais exécuté car le END {exit err}'met fin au script. Existe-t-il un moyen de définir le statut de retour sans quitter?
Stefan Lasiewski
6
@StefanLasiewski exit errtermine awk, il ne termine pas le script. Avez-vous set -edans ce script, par hasard? Si c'est le cas, vous avez dit au shell de quitter si une commande renvoie un état différent de zéro; si vous souhaitez tester l'état, utilisez if awk …; then echo ok; else echo fail; fi.
Gilles 'SO- arrête d'être méchant'
@Giles: Oui, ce script est set -edéfini. Cela explique l'étrange comportement que je vois. Merci d'avoir fait remarquer cela.
Stefan Lasiewski
1
Si vous prévoyez d'utiliser la sortie avec l' &&opérateur de bash , il convient de garder à l'esprit que "0 est vrai mais faux est 1 dans le shell" .
Skippy le Grand Gourou
7

Je cherchais quelque chose de similaire à grep, où il quittera 1 si aucune correspondance n'est trouvée. Voici l'équivalent avec awk:

awk '
BEGIN   {z=1}
/bravo/ {z=0; print}
END     {exit z}
' alpha.txt

Exemple

Steven Penny
la source
0

Cela ne répond pas aux exigences exactes de l'OP, mais si vous ne vous souciez que du code retour et que vous n'avez pas besoin d'imprimer les lignes qui correspondent, de la même manière que grep -q, vous pouvez modifier la réponse @geekasaur pour quitter après la première correspondance, ce qui, pour une entrée énorme les fichiers gagneraient du temps si l'erreur se trouvait au début du fichier. Si tout /etc/passwdva bien ne se qualifie pas pour vous!

awk -F: 'NF != 7 {err = 1; exit;}
     END {exit err}' /etc/passwd
Mark Stewart
la source
1
awk -F: 'NF != 7 {exit 1}'fera de même.
Stéphane Chazelas