2013-04-17 10 views
8

Potrzebuję wyszukać plik w poszukiwaniu ciągu znaków, usunąć wszystkie wiersze zawierające ciąg, a także usunąć dwie linie następujące po dowolnej linii zawierającej ciąg. Miałem nadzieję, że mogę tego dokonać za pomocą czegoś takiego ...Łączenie opcji -v i -A w grep

$ grep -v -A 2 two temp.txt 
one 
five 
$ 

... ale niestety to nie działa. Czy istnieje prosty sposób na wykonanie polecenia grep lub innego polecenia powłoki?

Odpowiedz

5

następujące prace zarówno z GNU sed i z OS X.

$ sed '/two/{N;N;d;}' temp.txt 
one 
five 
  • linia znaleźć pasujące two
  • przeczytać w dwóch kolejnych liniach
  • je usunąć
+0

Zarówno twoja odpowiedź, jak i @ JohnKugelman są zwięzłe, oboje pracują na GNU/Linuksie i nie działają na OS X (nie jest to dla mnie wielka sprawa w tym konkretnym zadaniu). Aby podać krótkie wyjaśnienie składni, zaakceptowana odpowiedź trafia do Ciebie. Dzięki. –

+2

Dodaj średnik po d i. Wymuś klamrę i powinna działać również na MacOS X. –

2

z GNU sed:

sed '/two/,+2d' temp.txt 

Używa składni dwóch adresów (addr1,addr2), aby dopasować linie do słowa dwa (/two/) plus dwa wiersze po (+2). Komenda d usuwa te linie.

+0

Jedyne co mogę sobie wyobrazić to to, że może używają starszego, nie GNU sed, bez opcji '+ number'. Ale skoro to działa (i nie podoba mi się to, że prowadzą downmoterów), oto głos na odwrócenie tego. – paxdiablo

3

Można to zrobić z awk, zgodnie z poniższym transkryptu:

pax> echo 'one 
two 
three 
four 
five' | awk '/two/ {skip=3} skip>0 {skip--;next} {print}' 

one 
five 

Zasadniczo uruchamia licznik linii wyrzucić (3), gdy stwierdzi ciąg two na linii. Następnie wyrzuca te linie, aż licznik przeskoku osiągnie zero. Zostanie wydrukowana każda linia, która nie jest oznaczona do pominięcia.

+0

Ma to tę zaletę, że obsługuje 'jeden dwa trzy dwa trzy cztery pięć' →' jeden pięć' poprawnie. –

1

Oto sposób zrobić to z Perl:

$ perl -ne'if (/two/){$x=<>;$x=<>;}else{print}' temp.txt 
one 
five 

-n jest niejawna pętla nad wejściem. Jeśli pasujesz do /two/, przeczytaj kolejne dwa wiersze, w przeciwnym razie wydrukuj linię, w której się znajdujesz.

Problem polega jednak na tym, że jeśli masz trzecią lub czwartą linię pasującą do/dwóch /, to nadal otrzymasz takie samo wyjście. Rozwiązanie @ paxdiablo jest bardziej kompletne. Ale mój jest bardziej Q & D.