2013-07-30 10 views
5

Jak łatwo wydrukować linię powyżej meczu i pominąć sam mecz? grep-A, -B i -o opt nie rozwiąż go. Może trochę magii awk?grep - drukuj wiersz wcześniej, nie drukuj mecz

na przykład:

$ cat foo.txt 
bar 
foo 
baz 
foo 

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

Edit

  • w przypadku gdy linia 2 i 3 ma "foo", następnie linia 1 i 2 powinny być drukowane (chociaż nie jestem bardzo surowe tutaj)

Dodatkowa funkcja: rozważ przykład:

bar 
foo 
baz 
foo 
foo 

ta powinna idealnie powrócić

bar 
baz 
foo 
+1

Co z '-B'? –

+1

@ AdrianFrühwirth drukuje poprzednią linię ORAZ pasującą linię. – Barmar

+0

co dwie linie ciągłe pasują do 'foo'? wydrukować pierwszą linię? lub zignorować oba? – Kent

Odpowiedz

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

Pierwsza klauzula zapisuje każdą linię non-foo w zmiennej. Druga klauzula wypisze ostatnią zapisaną linię, gdy linia pasuje do foo.

Działa to również (i obsługuje przypadek, gdzie masz dwa foo linie w jednym rzędzie):

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

Z grep można zrobić:

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

drugim filtry poleceń zewnątrz foo linie i przekładki, które są drukowane pomiędzy dopasowanymi blokami.

+0

Jeśli linia zawierająca 'foo' powinna zostać wydrukowana, jeśli występuje linia zgodna z' foo', refactor do 'awk '/ foo/{print line} {line = 0 0}' foo.txt' – tripleee

+1

Nie powinno się' ' awk '/ foo/{print line} {line = 0 $}' foo.txt' wystarczy? –

+0

@ AdrianFrühwirth: Proszę zaksięgować to jako odpowiedź, zachowuje się lepiej w przypadku powtarzania pasującego wzorca (patrz edytowane pytanie) –

2

Wystarczy ustawić p do wzorca chcesz:

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