Ich versuche, nach allen Fällen zu suchen, in denen Ui\.
nicht Line
oder nur der Brief folgtL
Was ist der richtige Weg, um einen regulären Ausdruck zu schreiben, um alle Instanzen einer bestimmten Zeichenfolge zu finden, gefolgt von einer anderen Zeichenfolge?
Lookaheads verwenden
grep "Ui\.(?!L)" *
bash: !L: event not found
grep "Ui\.(?!(Line))" *
nothing
regex
grep
regex-lookarounds
Lee Quarella
quelle
quelle
set +o histexpand
in Bash oderset +H
YMMV.Antworten:
Negativer Lookahead, nach dem Sie suchen, erfordert ein leistungsfähigeres Werkzeug als der Standard
grep
. Sie benötigen einen PCRE-fähigen grep.Wenn Sie GNU haben
grep
, unterstützt die aktuelle Version Optionen-P
oder--perl-regexp
und Sie können dann den gewünschten regulären Ausdruck verwenden.Wenn Sie keine (ausreichend aktuelle) Version von GNU haben
grep
, sollten Sie in Betracht ziehen, diese zu erwerbenack
.quelle
!
als Sonderzeichen behandelt wird .-P
nicht unterstützt werden, versuchen Sie es erneut mit dem Rohrleitungsergebnisgrep --invert-match
, zgit log --diff-filter=D --summary | grep -E 'delete.*? src' | grep -E --invert-match 'xml'
. Stellen Sie sicher, dass Sie die Antwort von @Vinicius Ottoni positiv bewerten.Die Antwort auf einen Teil Ihres Problems ist hier, und ack würde sich genauso verhalten: Ack & negativer Lookahead geben Fehler
Sie verwenden doppelte Anführungszeichen für grep, wodurch bash "
!
als Befehl zum Erweitern des Verlaufs interpretieren " kann.Sie müssen Ihr Muster in EINZELZITATE einwickeln:
grep 'Ui\.(?!L)' *
Allerdings sehen @ JonathanLeffler Antwort auf die Probleme mit negativen Lookaheads in Standard - Adresse
grep
!quelle
grep
mit der Funktionalität von Standardgrep
, wobei der Standard fürgrep
POSIX ist. Was Sie sagen, ist auch wahr - ich führe Bash mit deaktivierten C-Shell-Barbaren aus (denn wenn ich eine C-Shell wollte, würde ich eine verwenden, aber ich möchte keine), damit!
mich das Zeug nicht betrifft - Aber um negative Lookaheads zu erhalten, benötigen Sie einen Nicht-Standardgrep
.Sie können wahrscheinlich keine negativen Standard-Lookaheads mit grep ausführen, aber normalerweise sollten Sie in der Lage sein, ein gleichwertiges Verhalten mit dem "inversen" Schalter '-v' zu erzielen. Auf diese Weise können Sie einen regulären Ausdruck für die Ergänzung dessen erstellen, was Sie anpassen möchten, und ihn dann durch 2 Greps leiten.
Für den fraglichen regulären Ausdruck könnten Sie so etwas tun
quelle
Wenn Sie eine Regex-Implementierung verwenden müssen, die keine negativen Lookaheads unterstützt, und es Ihnen nichts ausmacht, zusätzliche Zeichen * zuzuordnen, können Sie negierte Zeichenklassen
[^L]
, Alternation|
und das Ende des String-Ankers verwenden$
.In deinem Fall
grep 'Ui\.\([^L]\|$\)' *
macht der Job.Ui\.
entspricht der Zeichenfolge, an der Sie interessiert sind\([^L]\|$\)
Entspricht einem anderen Zeichen alsL
oder dem Zeilenende:[^L]
oder$
.Wenn Sie mehr als nur ein Zeichen ausschließen möchten, müssen Sie nur mehr Abwechslung und Negation darauf werfen. Zu finden
a
, gefolgt vonbc
:grep 'a\(\([^b]\|$\)\|\(b\([^c]\|$\)\)\)' *
Welches ist entweder (
a
gefolgt von nichtb
oder gefolgt vom Ende der Zeile:a
dann[^b]
oder$
) oder (a
gefolgt vonb
dem entweder gefolgt von nichtc
oder gefolgt von dem Ende der Zeile:a
dannb
, dann[^c]
oder$
.Diese Art von Ausdruck wird selbst mit einer kurzen Zeichenfolge ziemlich unhandlich und fehleranfällig. Sie könnten etwas schreiben, um die Ausdrücke für Sie zu generieren, aber es wäre wahrscheinlich einfacher, nur eine Regex-Implementierung zu verwenden, die negative Lookaheads unterstützt.
* Wenn Ihre Implementierung nicht erfassende Gruppen unterstützt , können Sie das Erfassen zusätzlicher Zeichen vermeiden.
quelle
Wenn Ihr grep -P oder --perl-regexp nicht unterstützt und Sie PCRE-fähiges grep installieren können, z. B. "pcregrep", benötigt es keine Befehlszeilenoptionen wie GNU grep, um Perl-kompatibles reguläres zu akzeptieren Ausdrücke, du rennst einfach
Sie benötigen keine weitere verschachtelte Gruppe für "Line" wie in Ihrem Beispiel "Ui. (?! (Line))" - die äußere Gruppe ist ausreichend, wie ich oben gezeigt habe.
Lassen Sie mich Ihnen ein weiteres Beispiel für negative Aussagen geben: Wenn Sie eine Liste von Zeilen haben, die von "ipset" zurückgegeben werden, wobei jede Zeile die Anzahl der Pakete in der Mitte der Zeile anzeigt und Sie keine Zeilen mit null Paketen benötigen, Sie nur Lauf:
Wenn Sie Perl-kompatible reguläre Ausdrücke mögen und Perl haben, aber kein pcregrep haben oder Ihr grep --perl-regexp nicht unterstützt, können Sie einzeilige Perl-Skripte verwenden, die genauso funktionieren wie grep:
Perl akzeptiert stdin genauso wie grep, z
quelle