web-dev-qa-db-fra.com

Comment 'grep' un flux continu?

Est-il possible d'utiliser grep sur un flux continu?

Ce que je veux dire est en quelque sorte une commande tail -f <file>, mais avec grep sur la sortie afin de ne conserver que les lignes qui m'intéressent.

J'ai essayé tail -f <file> | grep pattern mais il semble que grep ne puisse être exécuté qu'une fois _ tail terminé, c'est-à-dire jamais.

658
Matthieu Napoli

Activez le mode de mise en mémoire tampon de la ligne grep lorsque vous utilisez BSD grep (FreeBSD, Mac OS X, etc.)

tail -f file | grep --line-buffered my_pattern

Vous n'avez pas besoin de faire cela pour GNU grep (utilisé sur pratiquement tous les systèmes Linux), car il sera effacé par défaut (YMMV pour d'autres systèmes de type Unix, tels que SmartOS, AIX ou QNX).

1228
tad

J'utilise le tail -f <file> | grep <pattern> tout le temps.

Il attendra que grep débute, pas jusqu'à la fin (j'utilise Ubuntu).

113
Irit Katriel

Je pense que votre problème est que grep utilise un tampon de sortie. Essayer

tail -f file | stdbuf -o0 grep my_pattern

il va définir le mode de mise en tampon de sortie de grep sur non tamponné.

59
XzKto

Dans la plupart des cas, vous pouvez tail -f /var/log/some.log |grep foo et tout se passera bien.

Si vous devez utiliser plusieurs greps sur un fichier journal en cours d'exécution et que vous ne recevez aucune sortie, vous devrez peut-être coller le commutateur --line-buffered dans votre milie grep (s), comme ceci :

tail -f /var/log/some.log | grep --line-buffered foo | grep bar
10
Dale Anderson

Si vous voulez trouver des correspondances dans le fichier entier (pas seulement la queue) et que vous voulez qu'il reste en attente des nouvelles correspondances, cela fonctionne parfaitement:

tail -c +0 -f <file> | grep --line-buffered <pattern>

Le drapeau -c +0 indique que la sortie doit commencer 0 octets (-c) à partir du début (+) du fichier.

10
Ken Williams

Je n'ai vu personne proposer mon adresse habituelle pour cela:

less +F <file>
ctrl + c
/<search term>
<enter>
shift + f

Je préfère cela, car vous pouvez utiliser ctrl + c pour arrêter et parcourir le fichier à tout moment, puis appuyez simplement sur shift + f pour revenir à la recherche en direct et en continu.

5
Hans.Loven.work

sed serait un meilleur choix ( éditeur de flux )

tail -n0 -f <file> | sed -n '/search string/p'

et si vous voulez que la commande tail se ferme une fois que vous avez trouvé une chaîne particulière:

tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'

Évidemment, un bashisme: $ BASHPID sera l’identifiant du processus de la commande tail. La commande sed est située juste après la queue du pipeline. L'id du processus sed sera donc $ BASHPID + 1.

3
Christian Herr

vous pouvez considérer cette réponse comme une amélioration .. en général, j'utilise

tail -F <fileName> | grep --line-buffered  <pattern> -A 3 -B 5

-F est préférable en cas de rotation de fichier (-f ne fonctionnera pas correctement si le fichier est pivoté)

-A et -B sont utiles pour obtenir des lignes juste avant et après l'apparition du motif .. ces blocs apparaîtront entre les séparateurs de lignes en pointillés

Mais pour moi, je préfère faire ce qui suit

tail -F <file> | less

c'est très utile si vous voulez chercher dans les logs en streaming

3
mebada

Cette commande fonctionne pour moi (Suse):

mail-srv:/var/log # tail -f /var/log/mail.info |grep --line-buffered LOGIN  >> logins_to_mail

collecte des connexions au service de messagerie

1
user10584393

Oui, cela fonctionnera très bien. Grep et la plupart des commandes Unix agissent sur les flux ligne par ligne. Chaque ligne qui sort de la queue sera analysée et transmise si elle correspond.

0
Caleb