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
BEGIN
ouEND
fort>.Modèles spéciaux
L'utilitaire awk doit reconnaître deux modèles spéciaux,
BEGIN
etEND
. Chaque modèleBEGIN
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 fonctiongetline
(voir Entrée / Sortie et Général Fonctions) dans une actionBEGIN
antérieure et avant que l'affectation de la ligne de commande ne soit effectuée Chaque modèleEND
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èlesBEGIN
doivent être exécutées dans l'ordre spécifié dans le programme, tout comme les actionsEND
. Un modèleEND
peut précéder un modèleBEGIN
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.
Vous devez simplement mettre la même commande dans les blocs
/ foo /
etEND
commeawk '/ 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 commeawk -f myawkscript.awk myfile.txt
Awk oublié avait des fonctions. Merci!