it-swarm.com.de

Wie zeige ich nur die nächste Zeile nach der übereinstimmenden an?

grep -A1 'blah' logfile

Dank dieses Befehls erhalte ich für jede Zeile, die 'blah' enthält, die Ausgabe der Zeile, die 'blah' enthält, und der nächsten Zeile, die in der Protokolldatei folgt. Es mag einfach sein, aber ich kann keine Möglichkeit finden, die Zeile mit 'blah' und nur show next line in the output wegzulassen.

197
facha

sie können mit awk versuchen:

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

wenn du bei grep bleiben willst:

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

oder

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

Piping ist dein Freund ...

Verwenden grep -A1 um die nächste Zeile nach einer Übereinstimmung anzuzeigen, leiten Sie das Ergebnis an tail weiter und greifen Sie nur 1 Zeile zu,

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

Tolle Antwort von Raim, war sehr nützlich für mich. Es ist trivial, dies zu erweitern, um z.B. Zeile 7 nach dem Muster

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

Wenn die nächsten Zeilen niemals 'blah' enthalten, können Sie sie filtern mit:

grep -A1 blah logfile | grep -v blah

Die Verwendung von cat logfile | ... wird nicht gebraucht.

6
ott--

Im Allgemeinen bin ich damit einverstanden, dass Sie hier viele Fragen stellen und dass ein anderes Tool die bessere Lösung sein könnte. Aber in einer eingebetteten Umgebung möchte ich möglicherweise nicht nur sed oder awk, um dies zu tun. Ich habe festgestellt, dass die folgende Lösung funktioniert (sofern es sich nicht um zusammenhängende Übereinstimmungen handelt):

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

Passen Sie sie grundsätzlich an, indem Sie für jede Übereinstimmung eine Kontextzeile anhängen und diese dann durch eine inverse Übereinstimmung Ihres ursprünglichen Musters leiten, um diese zu entfernen. Dies bedeutet natürlich, dass Sie davon ausgehen können, dass Ihr Muster nicht in der "nächsten" Zeile angezeigt wird.

5
Travis Griggs

Ich kenne keine Möglichkeit, dies mit grep zu tun, aber es ist möglich, awk zu verwenden, um das gleiche Ergebnis zu erzielen:

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

Bisher wurden viele gute Antworten auf diese Frage gegeben, aber ich vermisse immer noch eine mit awk, die getline nicht verwendet. Da im Allgemeinen , ist es nicht notwendig getline zu verwenden, würde ich gehen für:

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

oder

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

Die Logik besteht immer darin, die Zeile zu speichern, in der "blah" gefunden wird, und dann die Zeilen zu drucken, die eine Zeile nach der anderen liegen.

Prüfung

Beispieldatei:

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

Holen Sie sich alle Zeilen nach "bla". Dies gibt ein weiteres "bla" aus, wenn es nach dem ersten erscheint.

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

Holen Sie sich alle Zeilen nach "blah", wenn sie nicht selbst "blah" enthalten.

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

Perl-Einzeiler-Alarm

nur zum Spaß ... drucke nur eine Zeile nach dem Match

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

noch mehr spaß ... drucke die nächsten zehn zeilen nach dem spiel aus

Perl -lne '[email protected],(($.+1)..($.+10))if/match/;[email protected]&&print' data.txt

ein bisschen schummeln, da es tatsächlich zwei Befehle gibt

4
beasy

Anscheinend verwenden Sie dort das falsche Werkzeug. Grep ist nicht so raffiniert, ich denke, Sie möchten awk als Werkzeug für diesen Job einsetzen:

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

Wenn Sie irgendwelche Probleme haben, lassen Sie es mich wissen, ich denke, es lohnt sich, ein bisschen awk zu lernen, es ist ein großartiges Werkzeug :)

p.s. Dieses Beispiel gewinnt keinen "unnützen Einsatz von Katzen" -Preis;) http://porkmail.org/era/unix/award.html

3
sillyMunky