web-dev-qa-db-fra.com

Comment afficher uniquement la ligne suivante après celle qui correspond?

grep -A1 'blah' logfile

Grâce à cette commande pour chaque ligne contenant "blah", je reçois le résultat de la ligne contenant "blah" et la ligne suivante qui suit dans le fichier journal. C'est peut-être simple, mais je ne peux pas trouver un moyen d'omettre la ligne qui contient 'blah' et seulement montre la ligne suivante dans la sortie.

197
facha

vous pouvez essayer avec awk:

awk '/blah/{getline; print}' logfile
173
Michał Šrajer

si vous voulez vous en tenir à grep:

grep -A1 'blah' logfile|grep -v "blah"

ou

sed -n '/blah/{n;p;}' logfile
138
Kent

Piping est votre ami ...

Utilisez grep -A1 pour afficher la ligne suivante après une correspondance, puis transmettez le résultat à tail et ne saisissez qu'une ligne.

cat logs/info.log | grep "term" -A1 | tail -n 1
29
weisjohn

Excellente réponse de Raim, m'a été très utile. Il est trivial d'étendre ceci pour imprimer par exemple. ligne 7 après le motif

awk -v lines=7 '/blah/ {for(i=lines;i;--i)getline; print $0 }' logfile
13
souter

Si ces prochaines lignes ne contiennent jamais 'blah', vous pouvez les filtrer avec:

grep -A1 blah logfile | grep -v blah

L'utilisation de cat logfile | ... n'est pas nécessaire.

6
ott--

En général, je conviens que vous demandez beaucoup de grep ici, et qu'un autre outil pourrait être la meilleure solution. Mais dans un environnement intégré, je ne souhaite peut-être pas utiliser sed ou awk simplement pour le faire. J'ai trouvé la solution suivante qui fonctionne (tant que ce ne sont pas des correspondances contiguës):

grep -A1 AT\+CSQ wvdial.out | grep -v AT\+CSQ

Fondamentalement, faites-les correspondre, en ajoutant une ligne de contexte pour chaque correspondance, puis dirigez-les vers une correspondance inverse de votre modèle d'origine pour les éliminer. Bien entendu, cela signifie que vous pouvez supposer que votre modèle n'apparaît pas dans la ligne "suivante".

5
Travis Griggs

Je ne connais aucun moyen de faire cela avec grep, mais il est possible d'utiliser awk pour obtenir le même résultat:

awk '/blah/ {getline;print}' < logfile
5
raimue

Beaucoup de bonnes réponses ont été données à cette question jusqu'à présent, mais il me manque encore une avec awk n'utilisant pas getline. Puisque, en général , il n’est pas nécessaire d’utiliser getline, je choisirais:

awk ' f && NR==f+1; /blah/ {f=NR}' file  #all matches after "blah"

ou

awk '/blah/ {f=NR} f && NR==f+1' file   #matches after "blah" not being also "blah"

La logique consiste toujours à stocker la ligne où se trouve "bla" puis à imprimer les lignes une ligne après.

Tester

Exemple de fichier:

$ cat a
0
blah1
1
2
3
blah2
4
5
6
blah3
blah4
7

Obtenez toutes les lignes après "blah". Ceci imprime un autre "bla" s'il apparaît après le premier.

$ awk 'f&&NR==f+1; /blah/ {f=NR}' a
1
4
blah4
7

Obtenez toutes les lignes après "bla" si elles ne contiennent pas "bla" elles-mêmes.

$ awk '/blah/ {f=NR} f && NR==f+1' a
1
4
7
5
fedorqui

alerte Perl sur une ligne

juste pour le plaisir ... n'imprimez qu'une ligne après le match

Perl -lne '$next=($.+1)if/match/;$.==$next&&print' data.txt

encore plus de plaisir ... imprimer les dix lignes suivantes après le match

Perl -lne 'Push@nexts,(($.+1)..($.+10))if/match/;$.~~@nexts&&print' data.txt

un peu tricher bien car il y a en fait deux commandes

4
beasy

On dirait que vous utilisez le mauvais outil ici. Grep n’est pas si sophistiqué que ça, je pense que vous voulez passer à l’outil suivant:

awk '/blah/ { getline; print $0 }' logfile

Si vous rencontrez des problèmes, faites-le moi savoir, je pense que cela vaut la peine d'apprendre un peu d'awk, c'est un excellent outil :)

p.s. Cet exemple ne permet pas de gagner une "utilisation inutile de chat award";) http://porkmail.org/era/unix/award.html

3
sillyMunky