web-dev-qa-db-fra.com

Comment appliquer un filtre à la sortie en temps réel de `tail -f`?

tail -f path

Ce qui précède produira instantanément des modifications dans le fichier, mais je veux appliquer un filtre à la sortie, ne montrer que lorsqu'il y a un mot-clé xxx dedans.

Comment aborder cela?

61
wamp

Avec Unix, vous pouvez diriger la sortie d'un programme dans un autre.

Donc, pour filtrer la queue, vous pouvez utiliser grep:

tail -f path | grep your-search-filter
87
AddersUK

Réponse courte: tail -f somefile | grep somepattern

Cependant, cela a tendance à manquer. Disons que vous suivez un fichier qui tourne souvent (s'il s'agit d'un journal de débogage, il peut être tourné plusieurs fois). Dans ce cas, tail -F Est votre ami. Je vous laisse chercher la différence.

Mais tail -f Et tail -F Impriment d'abord un tas de lignes, ce qui est souvent indésirable dans ce cas d'utilisation, alors dans ce cas, ajoutez -n0

tail -F -n0 somefile | grep somepattern

Ce sera bien, jusqu'à ce que vous souhaitiez effectuer un autre filtrage, puis vous devez vous méfier de la mise en mémoire tampon. stdout est mis en mémoire tampon par défaut lors de l'écriture sur un terminal mais lorsqu'il est entièrement mis en mémoire tampon lors de l'écriture dans un canal. Ainsi, les éléments suivants émettront des lignes dès qu'ils seront trouvés, car tail est explicitement mis en mémoire tampon (ou il vide sa sortie à la fin de chaque ligne), et grep est également line- tamponné parce que sa sortie va à votre terminal:

tail -F -n0 somefile | grep somepattern

Mais vous décidez ensuite d'utiliser quelque chose comme awk ou cut pour poursuivre le traitement de la sortie.

tail -F -n0 somefile | grep somepattern | awk '{print $3}'

Et maintenant vous vous demandez où est passée votre sortie ... en fonction du volume de journaux, vous pouvez trouver que vous obtenez la sortie, mais ce sera une page à la fois car maintenant la sortie standard de grep fonctionne de façon entièrement tamponnée, et donc awk le reçoit en entrée 4 Ko à la fois (par défaut).

Dans ce cas, vous pouvez dire à grep de toujours mettre la ligne stdout en mémoire tampon en utilisant l'option --line-buffered.

tail -F -n0 somefile | grep --line-buffered somepattern | ...

Cependant, la plupart des commandes n'ont pas d'analogue de --line-buffered. Dans le cas d'outils plus scriptables, vous pouvez utiliser une fonction pour vider la sortie (par exemple, dans awk, la fonction est fflush(), qui partage le même nom que son homologue C, tools comme Perl et Python a quelque chose de similaire).

Avec les goûts de cut, vous n'avez probablement pas de chance; ... mais vous pourriez essayer de rechercher unbuffer, ce qui est, je pense, quelque chose fourni par la chaîne d'outils expect (je ne l'ai jamais utilisé).

J'espère que vous avez trouvé cela utile.

À la vôtre, Cameron

16
Cameron Kerr

et vous pouvez utiliser plusieurs canaux et greps, et exclure des choses avec grep -v, obtenir une insensibilité à la casse avec grep -i, etc.

à savoir: queue -100f/var/log/messages | grep -V ACPI | grep -i ata

commencez à suivre 100 lignes à partir de la fin et continuez à suivre, excluez d'abord toutes les lignes avec ACPI, puis affichez les lignes avec ata, ATA ou tout mélange de celles-ci.

Les options ABC sont également utiles pour les lignes Après, Avant et Contexte (lignes avant et après).

2
Ronald Pottol