suivre un fichier journal mais n'afficher que des lignes spécifiques


29

Je suis un fichier journal avec le drapeau -f. Ensuite, je redirige ceci vers grep, pour ne trouver que les lignes qui contiennent "X". Cela fonctionne parfaitement bien. Maintenant, je veux rediriger ceci dans un autre grep, qui supprimera toutes les lignes contenant "Y". Lorsque j'ajoute le deuxième canal, le fichier cesse de se rafraîchir et il semble qu'aucune donnée ne vienne.

C'est la commande qui fonctionne: tail -f my_file.log | grep "X"

C'est la commande qui ne fait pas: tail -f my_file.log | grep "X" | grep -v "Y"

Comment dois-je structurer cela pour que la commande fonctionne?


1
essayez de faire un tuyau par un tuyau, changez la séquence, faites tail -f file|grep -v "Y". si la sortie est correcte, passez à l'ajout grep "X".
Aizuddin Zali

Réponses:


38

Comme la sortie de grepest mise en mémoire tampon, utilisez l' --line-bufferedoption de greppour activer la mise en mémoire tampon de ligne:

tail -f /path/to/log | grep --line-buffered 'X' | grep -v 'Y'

Si votre grepn'a pas l'option, vous pouvez utiliser stdbufcomme alternative:

tail -f /path/to/log | stdbuf -oL grep 'X' | grep -v 'Y'

1
Je me demande comment stdbufdit libstdbuf.soquels paramètres utiliser.
kasperd

@kasperd: variables d'environnement.
Nate Eldredge

1
@NateEldredge J'ai déjà recherché des variables d'environnement dans la sortie de diff -u <(env) <(stdbuf env)et n'en ai trouvé aucune. Mais maintenant je me rends compte que ce que j'aurais dû tester l'était diff -u <(env) <(stdbuf -oL env).
kasperd

Je suis aussi le même genre de problème. mon cas est, je dois imprimer toutes les lignes contiennent «aaa» et «bbb». La première solution ci-dessus ne fonctionne pas. La deuxième solution fonctionne pour «aaa» existe et «bbb» n'existe pas. les deux existent ne fonctionnent pas. ne donnant aucune sortie. ma commande ressemble à ceci: tail -f test.txt | stdbuf -oL grep 'aaa' | grep 'bbb' elle ne donne aucune sortie. Pourriez-vous m'aider s'il vous plait.
Sun

18

Je trouve normalement plus utile awkpour ce genre de vérifications logiques:

tail -f /path/to/log | awk '/X/ && !/Y/'
#                           ^^^    ^^^^
#                   this I want    but not this

Testé en ayant deux onglets, l'un dans lequel je continue d'écrire seq 20 >> myfileet l'autre ayant par exemple tail -f myfile | awk '/3/ && !/13/'.


15

Une autre approche serait d'utiliser une seule grepinvocation au lieu de deux et ainsi d'éviter le problème de mise en mémoire tampon. Utilisez simplement une expression régulière qui correspond à des lignes composées de 0 ou plusieurs caractères non Y, puis d'un X puis de 0 ou de plusieurs non Y jusqu'à la fin de la ligne "

tail -f /path/to/log | grep '^[^Y]*X[^Y]*$'
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.