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?
4 Réponses :
Non. Faites ceci à la place:
awk '
/foo/ { prtInfo() }
END { prtInfo() }
function prtInfo() { print "foo or END" }
'
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
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.
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.
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
BEGINouENDfort>.Modèles spéciaux
L'utilitaire awk doit reconnaître deux modèles spéciaux,
BEGINetEND. Chaque modèleBEGINdoit ê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 fonctiongetline(voir Entrée / Sortie et Général Fonctions) dans une actionBEGINantérieure et avant que l'affectation de la ligne de commande ne soit effectuée Chaque modèleENDdoit ê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
ENDne doivent pas être combinés avec d'autres modèles. code> les modèles doivent être autorisés. Les actions associées aux modèlesBEGINdoivent être exécutées dans l'ordre spécifié dans le programme, tout comme les actionsEND. Un modèleENDpeut précéder un modèleBEGINdans 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.
Vous devez simplement mettre la même commande dans les blocs
/ foo /etENDcommeawk '/ 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
.awkapproprié et de l'exécuter commeawk -f myawkscript.awk myfile.txtAwk oublié avait des fonctions. Merci!