Być precyzyjnym
Some text
begin
Some text goes here.
end
Some more text
i chcę wyodrębnić cały blok, który zaczyna się od „początku” do „końca”.
z awk możemy to zrobić awk '/begin/,/end/' text
.
Jak zrobić grep?
Być precyzyjnym
Some text
begin
Some text goes here.
end
Some more text
i chcę wyodrębnić cały blok, który zaczyna się od „początku” do „końca”.
z awk możemy to zrobić awk '/begin/,/end/' text
.
Jak zrobić grep?
Odpowiedzi:
Zaktualizowano 18 listopada 2016 r. (Ponieważ zmieniono zachowanie grep: grep z parametrem -P nie obsługuje teraz ^
i $
zakotwicza [w Ubuntu 16.04 z jądrem v: 4.4.0-21-generic]) ( niepoprawna (nie) poprawka )
$ grep -Pzo "begin(.|\n)*\nend" file
begin
Some text goes here.
end
Uwaga: w przypadku innych poleceń po prostu zamień kotwice „^” i „$” na kotwicę nowej linii '\n'
______________________________
Z poleceniem grep:
grep -Pzo "^begin\$(.|\n)*^end$" file
Jeśli nie chcesz uwzględniać wzorców „początek” i „koniec”, użyj grep z obsługą Lookbehind i Lookahead.
grep -Pzo "(?<=^begin$\n)(.|\n)*(?=\n^end$)" file
Możesz także użyć \K
powiadomienia zamiast twierdzenia Lookbehind.
grep -Pzo "^begin$\n\K(.|\n)*(?=\n^end$)" file
\K
opcja zignoruj wszystko przed dopasowaniem wzorca i zignoruj sam wzorzec.
\n
służy do unikania drukowania pustych linii z wydruku.
Lub, jak sugeruje @AvinashRaj, istnieje prosty łatwy grep w następujący sposób:
grep -Pzo "(?s)^begin$.*?^end$" file
grep -Pzo "^begin\$[\s\S]*?^end$" file
(?s)
mówi grep, aby kropka pasowała do znaków nowej linii.
[\s\S]
dopasowuje dowolny znak, który jest albo spacją, albo spacją.
Ich wyniki bez uwzględnienia „początku” i „końca” są następujące:
grep -Pzo "^begin$\n\K[\s\S]*?(?=\n^end$)" file # or grep -Pzo "(?<=^begin$\n)[\s\S]*?(?=\n^end$)"
grep -Pzo "(?s)(?<=^begin$\n).*?(?=\n^end$)" file
zobacz pełny test wszystkich poleceń tutaj ( przestarzałe, ponieważ zachowanie grep z parametrem -P zostało zmienione )
^
wskaż początek linii i $
wskaż koniec linii. dodawano je do „początku” i „końca”, aby dopasować je, jeśli są sami w linii.
W dwóch poleceniach uciekłem, $
ponieważ używa on również funkcji „Command Substitution” ( $(command)
), która umożliwia wyjście polecenia zastępując nazwę polecenia.
-o, --only-matching
Print only the matched (non-empty) parts of a matching line,
with each such part on a separate output line.
-P, --perl-regexp
Interpret PATTERN as a Perl compatible regular expression (PCRE)
-z, --null-data
Treat the input as a set of lines, each terminated by a zero byte (the ASCII
NUL character) instead of a newline. Like the -Z or --null option, this option
can be used with commands like sort -z to process arbitrary file names.
grep -Pzo "(?<=begin\n)(.|\n)*(?=\nend)" file
aby nie drukować \n
znaku, który istnieje na początku linii.
grep -Pzo "(?s)begin.*?end" file
grep -Pzo "begin[\s\S]*?end" file
grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstützt
Tłumaczenie błędu jest coś w stylu:grep: a not protected ^ or $ is not supported with -Pz
grep
wydaje się zmieniły.