Wie gebe ich ein Muster für eine neue Zeile in grep?


91

Wie gebe ich ein Muster für eine neue Zeile in grep? Neue Zeile am Anfang, neue Zeile am Ende. Nicht der Weg des regulären Ausdrucks. So etwas wie \ n.


6
Es ist nicht klar, was Sie wollen. new line at the beginningist eine leere Zeile und new line at endgilt für jede Zeile in der Datei. Können Sie ein Beispiel posten?
PP

1
Eigentlich kann man einfach benutzen $. Es ist etwas begrenzt, aber in einfachen Fällen verwendbar.
Krzysztof Jabłoński

Antworten:


83

grep Muster werden mit einzelnen Zeilen abgeglichen, sodass ein Muster nicht mit einer in der Eingabe gefundenen neuen Zeile übereinstimmen kann.

Sie können jedoch Leerzeilen wie diese finden:

grep '^$' file
grep '^[[:space:]]*$' file # include white spaces 

Zumindest hat GNU grep die Option -z, mit der grep Zeilen durch Nullzeichen unterbricht. Es scheint jedoch keine Zeilenumbrüche oder \ n im Muster zu unterstützen, die mit Zeilenumbrüchen übereinstimmen, siehe Fehlerbericht .
Jarno

1
@jarno Es unterstützt \ n in Mustern mit der -P-Flagge
Rubystallion

91

versuchen Sie pcregrepstatt regelmäßig grep:

pcregrep -M "pattern1.*\n.*pattern2" filename

Mit dieser -MOption kann die Übereinstimmung über mehrere Zeilen hinweg erfolgen, sodass Sie nach Zeilenumbrüchen als suchen können \n.


21

Sie können diesen Weg benutzen ...

grep -P '^\s$' file
  • -Pwird für reguläre Perl-Ausdrücke verwendet (eine Erweiterung von POSIX grep).
  • \sPassen Sie die Leerzeichen an. Wenn gefolgt von *, stimmt es auch mit einer leeren Zeile überein.
  • ^stimmt mit dem Zeilenanfang überein. $stimmt mit dem Zeilenende überein.

2
-Pist eine GNU-Erweiterung. Ich kann es gut verwenden, wenn es die Situation erfordert (normalerweise lookahead / lookbehind), aber POSIX grep kann dies nur mit einer Datei tun [[:space:]].
Jordanm

1
Die Grep-Manpages von FWIW, Solaris und BSD (andere nicht überprüft) haben beide einen Absatz für -P. GNU ist sowieso Standard. :)
K3 --- rnc

1
Von der Handbuchseite: [-P] Diese Option wird in FreeBSD nicht unterstützt.
Marián Černý

Nein [-P] auch für MacOsX: grep [-abcdDEFGHhIiJLlmnOopqRSsUVvwxZ] [-A num] [-B num] [-C [num]] [-e Muster] [-f Datei] [--binary-files = Wert] [--color [= when]] [--colour [= when]] [--context [= num]] [--label] [--line-buffered] [--null] [pattern] [file. ..]
Niccolò

@ Niccolò Du wirst brew install grepGNU grep bekommen wollen , das in mehrfacher Hinsicht überlegen ist. apple.stackexchange.com/questions/193288/…
Herdrick

19

Dank @jarno kenne ich die Option -z und habe herausgefunden, dass bei Verwendung von GNU grep mit der Option -P eine Übereinstimmung \nmit möglich ist . :) :)

Beispiel:

grep -zoP 'foo\n\K.*'<<<$'foo\nbar'

Druckt bar


1
Großartig, beachte, dass ich in der Antwort keine Benachrichtigung über das "@jarno" bekomme.
Jarno

3
Das ist toll! Vielen Dank für das Teilen!
Alicia Tang

6

Für die Problemumgehung (ohne Verwendung eines nicht tragbaren -PZeichens) können Sie ein neues Zeilenzeichen vorübergehend durch ein anderes ersetzen und es wieder ändern, z.

grep -o "_foo_" <(paste -sd_ file) | tr -d '_'

Grundsätzlich sucht es nach exakter Übereinstimmung, _foo_wo _bedeutet \n(so __= \n\n). Sie müssen es nicht zurück übersetzen tr '_' '\n', da jedes Muster ohnehin in der neuen Zeile gedruckt _wird. Das Entfernen ist also ausreichend.


Verzeihen Sie meine Unwissenheit, aber ist die Verwendung der Prozesssubstitution nicht eine weitere NON-Posix-kompatible, daher nicht tragbare Funktion? in posix shell konnte ich nicht machen <(p paste -sd_ file )?
Menschheit und

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.