Antworten:
Sie suchen ein nicht gieriges (oder faules) Match. Um eine nicht gierige Übereinstimmung in regulären Ausdrücken zu erhalten, müssen Sie den Modifikator ?nach dem Quantifizierer verwenden. Zum Beispiel können Sie ändern .*zu.*? .
Standardmäßig werden grepkeine nicht gierigen Modifikatoren unterstützt, Sie können grep -Pjedoch die Perl-Syntax verwenden.
.dem Zeilenumbrüche abgeglichen werden können, als DOTALL- oder Einzeilenmodus bezeichnet . Ruby ist der einzige, der es mehrzeilig nennt . In den anderen Varianten ist Multiline der Modus, in dem die Anker ( ^und $) an den Liniengrenzen übereinstimmen können. Ruby hat keinen äquivalenten Modus, da sie in Ruby immer so funktionieren.
-Pwar eine völlig neue für mich, ich habe mich jahrelang glücklich gefreut und nur -E... so viele verschwendete Jahre benutzt! - Hinweis für sich selbst: Lesen Sie Manpages als (noch mehr!) Normale Sache neu, Sie verdauen nie genug Schalter und Optionen.
grepdies nicht unterstützt -P. Wenn Sie es jedoch verwenden egrep, können Sie das .*?Muster verwenden, um das gleiche Ergebnis zu erzielen. egrep -o 'start.*?end' text.html
-P, -Ewürde jedoch aufrufen, egrepdass die vorgeschlagenen Funktionen einwandfrei .*?funktionieren.
Eigentlich funktioniert das .*?nur in perl. Ich bin mir nicht sicher, wie die entsprechende grep-erweiterte Regexp-Syntax aussehen würde. Glücklicherweise können Sie die Perl-Syntax mit grep verwenden, grep -Pwürde also funktionieren, aber grep -Edas ist dasselbe, egrepwas nicht funktionieren würde (es wäre gierig).
Siehe auch: http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html
grep -Pfunktioniert nicht in GNU grep 2.9 - habe es gerade versucht (es macht keinen Fehler, wendet nur stillschweigend das nicht an ?. Intertestly auch nicht die nicht-Klasse zB:env|grep '[^\=]*\='
grep -POption oder keinen pgrepBefehl, aber es egrepfunktioniert hervorragend.
pgrepBefehl auf meiner OS X 10.9-Box, aber es ist ein völlig anderes Programm, dessen Zweck darin besteht, "Prozesse nach Namen zu finden oder zu signalisieren".
Mein grep, der funktioniert, nachdem ich Sachen in diesem Thread ausprobiert habe:
echo "hi how are you " | grep -shoP ".*? "
Stellen Sie einfach sicher, dass Sie jeder Ihrer Zeilen ein Leerzeichen hinzufügen
(Meins war eine zeilenweise Suche, um Wörter auszuspucken)
-shoPschöne Gedächtnisstütze :)
echo "bbbbb" | grep -shoP 'b.*?b'ist ein bisschen eine Lernerfahrung. Einzige Sache, die bei mir auch explizit faul funktioniert hat.
grepFür nicht gierige Übereinstimmungen in können grepSie eine negierte Zeichenklasse verwenden. Versuchen Sie mit anderen Worten, Platzhalter zu vermeiden.
Um beispielsweise alle Links zu JPEG-Dateien aus dem Seiteninhalt abzurufen, verwenden Sie Folgendes:
grep -o '"[^" ]\+.jpg"'
Um mit mehreren Zeilen umzugehen, leiten Sie die Eingabe xargszuerst durch . Verwenden Sie für die Leistung ripgrep.
Die kurze Antwort verwendet den nächsten regulären Ausdruck:
(?s)<car .*? model=BMW .*?>.*?</car>
Eine (etwas) kompliziertere Antwort lautet:
(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>
Dies ermöglicht es, car1 und car2 im folgenden Text abzugleichen
<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
Entschuldigung, ich bin 9 Jahre zu spät, aber das könnte für die Zuschauer im Jahr 2020 funktionieren.
Angenommen, Sie haben eine Zeile wie "Hello my name is Jello". Jetzt möchten Sie die Wörter finden, die mit 'H'und 'o'mit einer beliebigen Anzahl von Zeichen dazwischen beginnen und enden . Und wir wollen keine Zeilen, wir wollen nur Worte. Dafür können wir den Ausdruck verwenden:
grep "H[^ ]*o" file
Dies gibt alle Wörter zurück. Dies funktioniert folgendermaßen: Es werden alle Zeichen anstelle von Leerzeichen dazwischen zugelassen. Auf diese Weise können wir mehrere Wörter in derselben Zeile vermeiden.
Jetzt können Sie das Leerzeichen durch ein beliebiges anderes Zeichen ersetzen. Angenommen, die erste Zeile war "Hello-my-name-is-Jello", dann können Sie Wörter mit dem Ausdruck erhalten:
grep "H[^-]*o" file
Ich weiß, dass es ein bisschen tot ist, aber ich habe gerade bemerkt, dass das funktioniert. Es hat sowohl Bereinigung als auch Bereinigung von meiner Ausgabe entfernt.
> grep -v -e 'clean\-\?up'
> grep --version grep (GNU grep) 2.20