Um genau zu sein
Some text
begin
Some text goes here.
end
Some more text
und ich möchte einen ganzen Block extrahieren, der von "begin" bis "end" beginnt.
mit awk können wir gerne machen awk '/begin/,/end/' text
.
Wie mache ich mit grep?
Um genau zu sein
Some text
begin
Some text goes here.
end
Some more text
und ich möchte einen ganzen Block extrahieren, der von "begin" bis "end" beginnt.
mit awk können wir gerne machen awk '/begin/,/end/' text
.
Wie mache ich mit grep?
Antworten:
Aktualisiert am 18. November 2016 (da das Grep-Verhalten geändert wurde: Grep mit -P-Parameter wird jetzt nicht unterstützt ^
und $
Anker [unter Ubuntu 16.04 mit Kernel v: 4.4.0-21-generic]) ( falsches (nicht-) Update )
$ grep -Pzo "begin(.|\n)*\nend" file
begin
Some text goes here.
end
Hinweis: Für andere Befehle ersetzen Sie einfach die Anker '^' & '$' durch Anker mit neuer Zeile. '\n'
______________________________
Mit grep Befehl:
grep -Pzo "^begin\$(.|\n)*^end$" file
Wenn Sie die Muster "begin" und "end" nicht in das Ergebnis aufnehmen möchten, verwenden Sie grep mit Lookbehind- und Lookahead-Unterstützung.
grep -Pzo "(?<=^begin$\n)(.|\n)*(?=\n^end$)" file
Sie können auch \K
notify anstelle von Lookbehind Assertion verwenden.
grep -Pzo "^begin$\n\K(.|\n)*(?=\n^end$)" file
\K
Option ignoriere alles vor dem Mustervergleich und ignoriere das Muster selbst.
\n
Dient zum Vermeiden des Druckens leerer Zeilen aus der Ausgabe.
Oder, wie @AvinashRaj andeutet, gibt es einfach leicht grep wie folgt:
grep -Pzo "(?s)^begin$.*?^end$" file
grep -Pzo "^begin\$[\s\S]*?^end$" file
(?s)
Weist grep an, den Punkt mit Zeilenumbrüchen abzustimmen.
[\s\S]
Stimmt mit jedem Zeichen überein, das entweder ein Leerzeichen oder ein Nicht-Leerzeichen ist.
Und ihre Ausgabe ohne "begin" und "end" ist wie folgt:
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
Den vollständigen Test aller Befehle finden Sie hier ( veraltet, da das Grep-Verhalten mit dem -P-Parameter geändert wurde ).
^
Zeigen Sie auf den Anfang einer Linie und $
auf das Ende einer Linie. Diese werden zu den Übereinstimmungen "Anfang" und "Ende" hinzugefügt, wenn sie alleine in einer Zeile stehen.
In zwei Befehlen bin ich geflüchtet, $
weil es auch "Command Substitution" ( $(command)
) verwendet, mit der die Ausgabe eines Befehls den Befehlsnamen ersetzen kann.
-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
, um \n
Zeichen, die in der Zeile vorhanden sind , nicht zu drucken .
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
Die Übersetzung des Fehlers grep: a not protected ^ or $ is not supported with -Pz
grep
scheint sich geändert zu haben.