Warum schlägt "grep fil *" fehl?

9

Ich fand echo file|grep fil*fehlgeschlagen, aber echo abcd|grep abc*erfolgreich.

Ich verstehe es nicht, kann jemand erklären?

tmpbin
quelle
Können Sie das System und die Version von grep hinzufügen? Dies liegt daran, dass mit gnugrep 2.16 (unter Ubuntu 14.04 LTS) kein Fehler generiert wird (Exit-Code 0) und die ersten drei Buchstaben übereinstimmen. Zum Beispiel echo file|grep fil*Antworten mit file.
Hastur
3
@Hastur Das Problem wird durch die Dateinamenerweiterung vor dem regulären Ausdruck verursacht. Mein Arbeitsverzeichnis enthält eine Datei mit dem Präfix "fil", jedoch keine Datei mit dem Präfix "abc". Daher wird "fil *" durch den Dateinamen ersetzt, "abc *" bleibt jedoch unverändert.
tmpbin
Danke, ich habe nicht darüber nachgedacht. Wenn ich meine Versuche mache, versuche ich sie in einem neuen Verzeichnis ...
Hastur

Antworten:

31

Es gibt zwei Probleme mit Ihrem Beispiel.

Das wichtigste ist, dass Sie davon ausgehen, dass reguläre Ausdrücke genauso funktionieren wie Glob-Muster , da *es sich um einen Platzhalter handelt, der "eine beliebige Folge von Zeichen" bedeutet. In regulären Ausdrücken, *bedeutet „ eine beliebige Anzahl des vorherigen Atom“ statt, so fil*Mittel , fgefolgt von inull oder mehr gefolgt lZeichen. Sie müssen sagen grep fil.*, um die beabsichtigte Bedeutung zu erhalten: .bedeutet "jedes einzelne Zeichen, das .*heißt" jede Folge von Zeichen ".

Das kleinere Problem ist, dass Sie nicht zitierte Sonderzeichen verwenden, die unter Glob-Regeln etwas bedeuten, was bedeutet, dass die Shell sie interpretieren kann. Wenn Sie Dateien im lokalen Verzeichnis haben die glob - Muster passende fil*oder abc*, würde die Schale sie erweitert , so grepwürde die erweiterten Dateinamen als Muster erhält, nicht die beabsichtigten RE. Wenn Sie solche Zeichen in der Befehlszeile verwenden, sollten Sie sie in Anführungszeichen setzen : echo file | grep 'fil.*'.

Warren Young
quelle