Est-il possible de l'utiliser grep
sur un flux continu?
Ce que je veux dire, c'est une sorte de tail -f <file>
commande, mais avec grep
sur la sortie pour ne garder que les lignes qui m'intéressent.
J'ai essayé tail -f <file> | grep pattern
mais il semble que grep
cela ne peut être exécuté qu'une fois tail
terminé, c'est-à-dire jamais.
tail -f file
fonctionne (je vois la nouvelle sortie en temps réel)Réponses:
Activer le
grep
mode de mise en mémoire tampon de ligne lors de l'utilisation de BSD grep (FreeBSD, Mac OS X, etc.)Vous n'avez pas besoin de le faire pour GNU grep (utilisé sur à peu près n'importe quel Linux) car il sera vidé par défaut (YMMV pour d'autres likes Unix tels que SmartOS, AIX ou QNX).
la source
strace
. Sans--line-buffered
cela, cela ne fonctionnera pas.tail -f | grep
, et le--line-buffered
résout pour moi (sur Ubuntu 14.04, GNU grep version 2.16). Où la logique "utiliser la mise en mémoire tampon de ligne si stdout est un tty" est-elle implémentée? Dans git.savannah.gnu.org/cgit/grep.git/tree/src/grep.c ,line_buffered
est défini uniquement par l'analyseur d'arguments.--line-buffered
obtenir aucune sortie. Cependant, après les tests, il semble que GNU grep fasse ce que vous décrivez. Donc, comme la plupart des choses Unix, cela dépend de la mise en œuvre de votre plate-forme. Étant donné que la question ne spécifiait pas la plate-forme, vos informations semblent fausses - après avoir examiné le code de grep BSD et l'avoir comparé à grep GNU, le comportement est définitivement contrôlé par l'option --line-buffered. C'est juste que seul GNU grep est vidé par défaut.J'utilise
tail -f <file> | grep <pattern>
tout le temps.Il attendra jusqu'à ce que grep se vide, pas jusqu'à ce qu'il se termine (j'utilise Ubuntu).
la source
Je pense que votre problème est que grep utilise un tampon de sortie. Essayer
il définira le mode de tampon de sortie de grep sur non tamponné.
la source
grep
.unbuffer
(dans leexpect-dev
paquet sur debian) est roi . J'utiliserais donc un tampon non plus sur stdbuf.top
avec stdbuf et unbuffer). Et il n'y a vraiment pas de solution «magique»: l'imbuffeur échoue parfois aussi, par exemple awk utilise une implémentation de tampon différente (stdbuf échouera aussi).stdbuf
, `unbuffer, et stdio buffering sur pixelbeat.org/programming/stdio_bufferingSi vous voulez trouver des correspondances dans le fichier entier (pas seulement la queue), et que vous voulez qu'il reste assis et attende de nouvelles correspondances, cela fonctionne bien:
L'
-c +0
indicateur indique que la sortie doit commencer0
bytes (-c
) à partir du début (+
) du fichier.la source
Dans la plupart des cas, vous pouvez
tail -f /var/log/some.log |grep foo
et cela fonctionnera très bien.Si vous avez besoin d'utiliser plusieurs greps sur un fichier journal en cours d' exécution et que vous trouvez que vous obtenez pas de sortie, vous devrez peut - être coller le
--line-buffered
commutateur dans votre milieu grep (s), comme suit:la source
vous pouvez considérer cette réponse comme une amélioration .. habituellement j'utilise
-F est meilleur en cas de rotation du fichier (-f ne fonctionnera pas correctement si le fichier tourne)
-A et -B sont utiles pour obtenir des lignes juste avant et après l'occurrence 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
cela est très utile si vous souhaitez rechercher dans les journaux en streaming. Je veux dire revenir en arrière et regarder en profondeur
la source
grep -C 3 <pattern>
, remplace -A <N> et -B <N> si N est identique.Personne n'a proposé mon go-to habituel pour cela:
Je préfère cela, car vous pouvez utiliser
ctrl + c
pour arrêter et parcourir le fichier à tout moment, puis appuyez simplement surshift + f
pour revenir à la recherche en direct en streaming.la source
sed serait un meilleur choix ( éditeur de flux )
tail -n0 -f <file> | sed -n '/search string/p'
puis si vous vouliez quitter la commande tail 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 la suivante après la queue dans le tube, donc l'id du processus sed sera $ BASHPID + 1.
la source
$BASHPID+1
) sera le vôtre est fausse dans de nombreuses situations, et cela ne résout en rien le problème de la mise en mémoire tampon, ce qui est probablement ce à quoi l'OP tentait de se renseigner. En particulier, en recommandantsed
plusgrep
semble ici comme simplement une question de (douteuse) préférence. (Vous pouvez avoir unp;q
comportementgrep -m 1
si c'est le point que vous essayez de livrer.)--line-buffered
ne l'a pas fait. Je ne comprends vraiment pas le moins 1.Oui, cela fonctionnera très bien.
Grep
et la plupart des commandes Unix fonctionnent sur les flux une ligne à la fois. Chaque ligne qui sort de la queue sera analysée et transmise si elle correspond.la source
grep
c'est la dernière commande de la chaîne de tuyaux, elle agira comme vous l'expliquez. Cependant, s'il est au milieu, il tamponnera environ 8k de sortie à la fois.Cette commande fonctionne pour moi (Suse):
collecte des connexions au service de messagerie
la source
vous ne réussirez certainement pas avec
lorsque vous utilisez "colortail" comme alias pour la queue, par exemple. en bash
vous pouvez vérifier par type d'alias si cela produit quelque chose comme un isias de queue isan de
colortail -n 30
. alors vous avez votre coupable :)Solution:
supprimer l'alias avec
assurez-vous que vous utilisez le «vrai» binaire de queue par cette commande
qui devrait produire quelque chose comme:
puis vous pouvez exécuter votre commande
Bonne chance.
la source
Utilisez awk (un autre excellent utilitaire bash) au lieu de grep où vous n'avez pas l'option de mise en mémoire tampon de ligne! Il diffusera en continu vos données depuis la queue.
voici comment vous utilisez grep
Voici comment utiliser awk
la source
{print $0}
est redondant, car l'impression est l'action par défaut lorsqu'une condition passe.)