3
votes

Dans awk, pouvez-vous utiliser un motif ET un bloc END ensemble?

Dans awk, vous pouvez effectuer une action pour un modèle donné, comme:

# echo foo | awk '/foo/ || END {print "foo or END"}'
awk: syntax error at source line 1
 context is
    /foo/ || >>>  END <<<  {print "foo or END"}
awk: bailing out at source line 1

ou vous pouvez effectuer une action à la fin de l'entrée, comme:

echo foo | awk 'END {print "END"}'

Mais il ne semble pas possible de faire les deux, comme:

echo foo | awk '/foo/ {print "foo"}'

Est-ce possible?

awk

4 commentaires

Vous devez simplement mettre la même commande dans les blocs / foo / et END comme awk '/ food / {print "foo or END"} END { print "foo or END"} si la logique du bloc est suffisamment complète, vous pouvez la déplacer vers une fonction et appeler la fonction à partir des deux blocs.


Compris, mais si le bloc est long, alors c'est beaucoup de code redondant ...


Bien, alors collez ce code dans une fonction et appelez la fonction à partir des deux blocs. Si c'est suffisamment complexe, envisagez de l'écrire comme un fichier .awk approprié et de l'exécuter comme awk -f myawkscript.awk myfile.txt


Awk oublié avait des fonctions. Merci!


4 Réponses :


6
votes

Non. Faites ceci à la place:

awk '
/foo/ { prtInfo() }
END   { prtInfo() }
function prtInfo() { print "foo or END" }
'


0 commentaires

0
votes

vous pouvez essayer cette solution de contournement

awk '{Last=$0} END{ if( Last ~ /foo/) print "action if" }' YourFile

mais ce n'est que pour la dernière ligne du dernier fichier


0 commentaires

0
votes

cela pourrait être plus simple

$ awk '/foo/{exit} END{print "foo or END"}'

exit exécutera le bloc END , vous n'avez donc pas besoin de répéter l'instruction.


2 commentaires

Mmmm ... qui ignorera toutes les lignes suivant foo , sûrement?


Oui, bien sûr sortie anticipée. La question que je comprends, trouver un "foo" ou pas de "foo" à la fin. Si vous voulez trouver tous les "foo", ce n'est pas la bonne approche.



0
votes

Non, vous ne pouvez pas faire une telle chose. Les instructions END sont exécutées lorsque la dernière ligne a été traitée et similaires à BEGIN ce sont des formes spéciales de motifs.

Structure générale du programme

Un programme awk est composé de paires de forme:

/foo/ || END { action }

Soit le modèle , soit l ' action (y compris l'accolade englobante caractères) peuvent être omis.

Un modèle est une expression valide, une plage spécifiée par deux expressions séparées par une virgule, ou l'un des deux modèles spéciaux BEGIN ou END fort>.

Modèles spéciaux

L'utilitaire awk doit reconnaître deux modèles spéciaux, BEGIN et END . Chaque modèle BEGIN doit être mis en correspondance une fois et son action associée doit être exécutée avant que le premier enregistrement d'entrée ne soit lu, sauf éventuellement en utilisant la fonction getline (voir Entrée / Sortie et Général Fonctions) dans une action BEGIN antérieure et avant que l'affectation de la ligne de commande ne soit effectuée Chaque modèle END doit être mis en correspondance une fois et son action associée exécutée après la lecture du dernier enregistrement d'entrée. Ces deux modèles doivent avoir des actions associées.

BEGIN et END ne doivent pas être combinés avec d'autres modèles. code> les modèles doivent être autorisés. Les actions associées aux modèles BEGIN doivent être exécutées dans l'ordre spécifié dans le programme, tout comme les actions END . Un modèle END peut précéder un modèle BEGIN dans un programme.

source: awk POSIX standard

L'instruction

pattern { action }

n'est donc pas autorisée car elle combine END avec un autre modèle.

Voir la réponse d'Ed Morton pour une solution élégante.


0 commentaires