Drukuj linie między (i włącznie) dwoma wzorami

16

Chcę zacząć grepowanie od linii, które mają CKna końcu linii, a przestać grepowanie, gdy linia ma Dna końcu. Próbowałem grep "$CK" "$D" file..txt, ale to nie zadziałało.

Wejście:

kkkkkkkkkkk   
jjjjjjjjjjjjjjjjjj  
gggggggggggg/CK  
JHGHHHHHHHH   
HJKHKKLKLLL   
JNBHBHJKJJLKKL  
JLKKKLLKJLKJ/D  
GGGGGGGGGGGGGG  
GGGGGGGGGGGGGG

Pożądana moc wyjściowa:

gggggggggggg/CK  
JHGHHHHHHHH   
HJKHKKLKLLL   
JNBHBHJKJJLKKL  
JLKKKLLKJLKJ/D
Rana Khan
źródło

Odpowiedzi:

21

Lepiej jest użyć lub

awk '/CK$/,/D$/' file.txt

LUB

sed -n '/CK$/,/D$/p' file.txt

Jeśli nalegasz na , oto sposób GNU grep

grep -oPz '(?s)(?<=\n)\N+CK\n.*?D(?=\n)' file.txt

Tutaj

-P aktywuje perl-regexp

-zustawia separator linii na NUL. Zmusza to grep do zobaczenia całego pliku jako jednej linii

-o drukuje tylko pasujące

(?s)aktywuje PCRE_DOTALL, więc .znajdzie dowolny znak lub nową linię

\N pasuje do wszystkiego oprócz nowej linii

.*?znaleziska. w trybie nonrereedy

(?<=..) to stwierdzenie, że jest to przeszłość

(?=..) to stwierdzenie dotyczące przyszłości

iruvar
źródło
dlaczego nie dodać slash? jak toawk '/\/CK/,/\/D/' input
Rahul Patil
@RahulPatil, to dlatego, że OP stwierdził „zacznij grepowanie od linii, które mają„ CK ”na końcu linii i przestań grepowanie, gdy linia ma„ D ””
iruvar
wydaje mi się, że dobrze rozumiesz regex .. Nie zrozumiałem tego poziomu, więc czy mógłbyś wyjaśnić to ostatnie z PCRE grep
Rahul Patil
@RahulPatil, dodał kilka wyjaśnień :-)
iruvar
@RohitPatil, chcę usunąć pasujący wybór z pliku. czy mogę to zrobić?
Rana Khan,
0

Jeśli używasz BSD grep(nie obsługuje parametru wyrażenia regularnego perl -P), oto obejście:

grep -o "aaa.*cdn" <(paste -sd_ file) | tr '_' '\n'

Działa to poprzez połączenie wszystkich linii (zastąpienie nowych linii _znakiem), sprawdzenie wzoru jednowierszowego i rozwinięcie linii z powrotem do pierwotnego stanu.

Jeśli używasz GNU grep, możesz osiągnąć dopasowanie wieloliniowe grep, ale musisz użyć perl-regexp dla grep( -P), jak wspomniano w innej odpowiedzi . Nadal możesz zainstalować GNU grepna macOS za pomocą brew install grepi ggrepzamiast tego użyj .


Alternatywnie możesz użyć, pcregrepktóry obsługuje wzorce wieloliniowe ( -M).


Możesz także użyć expolecenia, np .:

ex +"/aaa/;/cdn/p" -scq! file
kenorb
źródło