Jak wyświetlać linie po każdym dopasowaniu grep, aż do innego konkretnego dopasowania?

44

Wiem, że za pomocą "-A NUM"przełącznika mogę wydrukować określoną liczbę linii końcowych po każdym dopasowaniu. Zastanawiam się tylko, czy można wydrukować końcowe wiersze, dopóki po każdym dopasowaniu nie zostanie znalezione określone słowo. np. kiedy szukam „Słowa A”, chcę zobaczyć wiersz zawierający „Słowo A”, a także wiersze po nim, aż do wiersza zawierającego „Słowo D”.

kontekst:

Word A
Word B
Word C
Word D
Word E
Word F

Komenda:

grep -A10 'Word A'

Potrzebuję tego wyjścia:

Word A
Word B
Word C
Word D
Meysam
źródło

Odpowiedzi:

73

Wygląda na to, że chcesz wydrukować linie między „ Word A” a „ Word D” (włącznie). Sugeruję, aby użyć sedzamiast grep. Pozwala edytować zakres strumienia wejściowego, który zaczyna się i kończy na pożądanych wzorach. Powinieneś po prostu powiedzieć, sedaby wydrukować wszystkie linie w zasięgu i żadnych innych linii:

sed -n -e '/Word A/,/Word D/ p' file
saeedn
źródło
Wszelkie wskazówki, jak uczynić go wyjątkowym (dla każdej ogólnej sytuacji, nie tylko PO)?
2rs2ts
4
@ 2rs2ts, aby uczynić go ekskluzywnym, wystarczy dodać | sed -e '1d;$d', że usuwa pierwszą i ostatnią linię
holroy
A jeśli chcesz wykluczyć wszystkie linie pomiędzy - to znaczy, chcesz po prostu zobaczyć linie, które są poza dwoma dopasowaniami - wtedy: sed -n -e '/pattern A/,/pattern D/d; p'To mówi: „usuń ze wzoru A do wzoru D i wydrukuj wszystko inne”. Niestety ten mecz jest chciwy. Oznacza to, że jeśli wzory A i D pojawią się więcej niż jeden raz, dopasujesz od pierwszego wzoru A do ostatniego wzoru D. Obawiam się, że Perl lub Python są twoimi przyjaciółmi, jeśli tak jest.
fbicknel
16

dlaczego nie użyć awk?

awk '/Word A/,/Word D/' filename
cesar
źródło
2
wygląda na to, że sed jest w stanie to zrobić znacznie wydajniej, jeśli w grę wchodzi duża liczba plików. awk może być łatwiejszy do zapamiętania, ale sed wydaje się być wart lepkiej notatki w moim mózgu.
JimNim
1
awk jest lepszy, jeśli Word Dspada na tę samą linię co Word Ai być może gdzie indziej, np. Word A Word D\nWord Dz sed pokaże dwie linie, gdzie jako awk pokaże jedną. Dodatkowo nadal można używać zmiennych z awk, np. awk -v _word="Word A" '$0 ~ _word,/Word D/' "/some/file"Więc sed może być bardziej wydajny, ale w przypadku wyszukiwania dwóch ciągów znaków, które mogą, ale nie muszą spaść w tej samej linii, awk jest zdecydowanie bardziej niezawodny.
S0AndS0
wydaje się, że awk lepiej radzi sobie sprawę, że plik zawiera sekwencje Ai Bi chcesz tylko uchwycić to, co znajduje się pomiędzy każdej takiej sekwencji. wygląda na to, że sed przynajmniej nie stosuje się do tej semantyki.
Matan
9
perl -lne 'print if /Word A/ .. /Word D/' file

lub

cat file | perl -lne 'print if /Word A/ .. /Word D/'
vinian
źródło
1
+1, aby przeciwstawić się głosowaniu za przejazdem. Nadal bym tego używał sed, chyba że potrzebujesz mocy wyrażeń regularnych Perla, aby wybrać linie rozdzielające.
tripleee
Ludzie, którzy pisali sed w latach 70. muszą być wdzięczni :-)
Matan