Est-il possible de filtrer la sortie de la queue?

11

Je voudrais suivre un fichier, mais uniquement les lignes de sortie qui contiennent une certaine chaîne. Est-ce possible?

Abe Miessler
la source

Réponses:

32

utilisez grep. Son construit juste à cet effet.

Pour trouver des lignes d'une queue de / var / log / syslog qui contiennent "cron", lancez simplement:

tail -f /var/log/syslog | grep cron

Et comme il accepte tout sur stdin, vous pouvez également l'utiliser sur la sortie de toute autre commande, en canalisant de la même manière que ci-dessus (en utilisant le symbole |).

Ryan H
la source
8
Bien que cela soit essentiellement correct, il est important de réaliser que grepcela tamponnera lorsqu'il sera utilisé de manière non interactive, comme lorsqu'il fait partie d'un pipeline plus long. GNU grep 2.5.1 offre la --line-bufferedpossibilité de contourner ce problème lorsque l'élimination de grep du pipeline n'est pas une option. (Quand je dis que grep va tamponner, je veux dire que vous ne verrez pas la sortie tant que le tampon n'aura pas atteint quelque chose comme 4k.)
kojiro
Pour compléter le commentaire précédent, "tail -f" sous Linux moderne fonctionnera en boucle, en attendant plus d'entrée dans le fichier syslog. Pour que la commande se termine réellement avec le contenu existant du fichier, omettez le commutateur -f: tail / var / log / syslog | grep cron
Gnudiff
7
tail -f /var/log/messages | grep "myfilterword"

J'espère que cela pourra aider.

pablo
la source
4

Voici quelques autres idées qui, bien que moins simples, peuvent offrir une flexibilité supplémentaire intéressante:

Tout d'abord, vous pouvez filtrer avec awk au lieu de grep:

tail -f /var/log/messages | awk '/myfilterword/'

cela fonctionne exactement de la même manière que l'exemple utilisant grep. Vous pouvez développer cela en utilisant la puissance de awk, par exemple:

tail -f /var/log/messages | \
awk '/myfilterword/ { for (i=6; i<=NF; i++) printf("%s ", $i); printf("\n")}'

qui affichera le 6ème dans le dernier champ de la sortie (les champs sont séparés par des espaces)

Une autre idée similaire consiste à utiliser un perl one-liner:

tail -f /var/log/messages | perl -ne "/myfilterword/ and print"

qui fonctionne exactement comme grep. Peut-être que vous voulez un compteur de numéros de ligne et juste le 6ème champ? Que dis-tu de ça:

tail -f /var/log/messages | \ 
perl -lane "/myfilterword/ and printf \"%6d %s\n\",++\$a,\$F[6]"

Évidemment, toutes ces sortes de choses peuvent aussi être faites avec d'autres outils, mais je voulais illustrer qu'il existe des façons amusantes d'utiliser des langages plus généraux comme awk ou perl ici.

Phil Hollenback
la source
+1 grande élaboration sur la façon de développer plus loin que grep!
pablo
2

Une autre astuce à noter, si vous avez un fichier CSV avec des en-têtes que vous souhaitez omettre, par exemple:

% cat data.txt
fruit        dessert        calories
Apple        Pie            770
Banana       Pudding        625
Cherry       Cobbler        990
% tail -n +2 data.txt
Apple        Pie            770
Banana       Pudding        625
Cherry       Cobbler        990

Peu importe la longueur de l'entrée tail, le +n -2omettra la première ligne.

JeffG
la source