2013-07-30 16 views
5

Wie kann man die Zeile über dem Spiel einfach ausdrucken und das Spiel selbst überspringen? grep-A, -B und -o opt es nicht lösen. Vielleicht etwas awk Magie?grep - Zeile vorher drucken, nicht drucken Übereinstimmung

zum Beispiel:

$ cat foo.txt 
bar 
foo 
baz 
foo 

$ cat foo.txt | grep foo-SOMETHING 
bar 
baz 

bearbeiten

  • im Fall, wenn die Leitung 2 und 3 haben "foo", dann die Linie 1 und 2 gedruckt werden soll (obwohl ich bin nicht sehr streng hier)

Zusatzausstattung: das Beispiel betrachten:

Rückkehr ideal
bar 
foo 
baz 
foo 
foo 

sollte Dieses

bar 
baz 
foo 
+1

Was mit '-B' falsch? –

+1

@ AdrianFrühwirth druckt die vorhergehende Zeile UND die passende Zeile. – Barmar

+0

Was ist mit zwei durchgehenden Linien, die beide 'foo' entsprechen? die erste Zeile drucken? oder beide ignorieren? – Kent

Antwort

12
awk '!/foo/ { line = $0 } 
    /foo/ { print line }' foo.txt 

Die erste Klausel in einer Variablen jede nicht-foo Zeile speichert. Die zweite Klausel gibt die letzte gespeicherte Zeile aus, wenn die Zeile mit foo übereinstimmt.

Dies funktioniert auch (und behandelt den Fall, in dem Sie zwei foo Linien in Folge haben):

awk '/foo/ {print line} 
    {line = $0}' foo.txt 

Mit grep können Sie tun:

grep -B 1 foo foo.txt | grep -vE 'foo|^--$' 

Der zweite Befehl filtert die foo Linien und die Teiler, die zwischen den übereinstimmenden Blöcken gedruckt werden.

+0

Wenn eine Zeile, die 'foo' enthält, gedruckt werden soll, wenn eine Zeile folgt, die' foo' entspricht, refactor zu 'awk'/foo/{Druckzeile} {line = $ 0} 'foo.txt' – tripleee

+1

Sollte nicht ' awk '/ foo/{Druckzeile} {line = $ 0}' foo.txt' ist ausreichend? –

+0

@ AdrianFrühwirth: Bitte posten Sie es als Antwort, es verhält sich besser im Umgang mit wiederholten übereinstimmenden Muster (siehe bearbeitete Frage) –

2

Stellen Sie einfach p dem Muster Sie wollen:

$ awk '$0~p{print a}{a=$0}' p="foo" file 
bar 
baz 
foo 
1
awk '/foo/{print a}{a=$0}' your_file