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.
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.
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.
-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.
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 . :) :)
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
2
gerade gefunden
grep $'\r'
Es wird $'\r'für die Flucht im C-Stil in Bash verwendet.
new line at the beginning
ist eine leere Zeile undnew line at end
gilt für jede Zeile in der Datei. Können Sie ein Beispiel posten?$
. Es ist etwas begrenzt, aber in einfachen Fällen verwendbar.Antworten:
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:
quelle
versuchen Sie
pcregrep
statt regelmäßiggrep
:Mit dieser
-M
Option kann die Übereinstimmung über mehrere Zeilen hinweg erfolgen, sodass Sie nach Zeilenumbrüchen als suchen können\n
.quelle
Sie können diesen Weg benutzen ...
-P
wird für reguläre Perl-Ausdrücke verwendet (eine Erweiterung von POSIXgrep
).\s
Passen 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.quelle
-P
ist 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:]]
.-P
. GNU ist sowieso Standard. :)brew install grep
GNU grep bekommen wollen , das in mehrfacher Hinsicht überlegen ist. apple.stackexchange.com/questions/193288/…Dank @jarno kenne ich die Option -z und habe herausgefunden, dass bei Verwendung von GNU grep mit der Option -P eine Übereinstimmung
\n
mit möglich ist . :) :)Beispiel:
grep -zoP 'foo\n\K.*'<<<$'foo\nbar'
Druckt
bar
quelle
Für die Problemumgehung (ohne Verwendung eines nicht tragbaren
-P
Zeichens) können Sie ein neues Zeilenzeichen vorübergehend durch ein anderes ersetzen und es wieder ändern, z.Grundsätzlich sucht es nach exakter Übereinstimmung,
_foo_
wo_
bedeutet\n
(so__
=\n\n
). Sie müssen es nicht zurück übersetzentr '_' '\n'
, da jedes Muster ohnehin in der neuen Zeile gedruckt_
wird. Das Entfernen ist also ausreichend.quelle
<(p paste -sd_ file )
?gerade gefunden
Es wird
$'\r'
für die Flucht im C-Stil in Bash verwendet.in diesem Artikel
quelle