Wie unterscheiden sich reguläre Ausdrücke von Platzhaltern, die zum Filtern von Dateien verwendet werden?

15

Während wir verwenden *, um null oder mehr vorherige Zeichen in zu bezeichnen grep, verwenden wir *.c, um alle C-Dateien zu finden, wenn wir es mit dem lsBefehl wie verwenden ls *.c. Könnte jemand sagen, wie sich die Verwendung von *in diesen beiden Fällen unterscheidet?

user3539
quelle

Antworten:

30

Globbing von Shell-Dateinamen und reguläre Ausdrücke verwenden einige der gleichen Zeichen und haben ähnliche Zwecke, aber Sie haben Recht, sie sind nicht kompatibel. Das Globbing von Dateinamen ist ein viel weniger leistungsfähiges System.

Im Dateinamen Globbing:

  • * bedeutet "null oder mehr Zeichen"

  • ? bedeutet "irgendein einzelnes Zeichen"

In regulären Ausdrücken müssen Sie jedoch .*"null oder mehr Zeichen" und ."ein beliebiges einzelnes Zeichen" bedeuten . A ?bedeutet in regulären Ausdrücken etwas ganz anderes: null oder eine Instanz des vorhergehenden RE-Elements.

Eckige Klammern ( []) scheinen in beiden Systemen auf dem System, auf dem ich dies schreibe, gleich zu funktionieren, zumindest in einfachen Fällen. Dazu gehören Dinge wie POSIX-Zeichenklassen (z. B.[:alpha:] ). Das heißt, wenn Sie Ihre Befehle für viele verschiedene Systemtypen benötigen, empfehle ich, nichts anderes als elementare Dinge wie Listen von Zeichen (z. B. [abeq]) und möglicherweise Zeichenbereiche (z [a-c]. B. ) zu verwenden.

Diese Unterschiede bedeuten, dass die beiden Systeme nur für einfache Fälle direkt austauschbar sind. Wenn Sie einen regulären Ausdruck für Dateinamen benötigen, müssen Sie dies auf eine andere Weise tun. find -regexist eine Option. (Beachten Sie, dass es find -nameübrigens auch eine Glob-Syntax gibt.)

Warren Young
quelle
2
Ich weiß nicht, dass es
Globbing
3
Darüber hinaus gibt es verschiedene Geschmacksrichtungen von Regex. Nicht alle regulären Ausdrücke sind gleich! Und Sie haben viele andere Pattern - Matching - Systeme, wie zum Beispiel SQL wie , wo '%'Mittel '*'.
Mr Lister
4
Zwei Hauptvarianten von RegExp sind POSIX und PCRE (Perl Compatible RE). Letzteres ist weniger langwierig und hat einige weitere Funktionen. Unix-Tools und -Shells verwenden im Allgemeinen POSIX. Die meisten Programmiersprachen mit integrierten regulären Ausdrücken (außer Shell) verwenden PCRE. Achten Sie einfach auf den Unterschied, wenn Sie online lesen.
Goldlöckchen
11

Beantwortung der Frage im Originaltitel:

Warum unterscheiden sich reguläre Ausdrücke von denen, die zum Filtern von Dateien verwendet werden?

Die Dateinamenerweiterung geht den regulären Ausdrücken voraus, die bereits unter den meisten Betriebssystemen (Platzhalter- / Joker-Zeichen) vorhanden waren, und ist viel einfacher und intuitiver als letztere.

Während *.txtes für Gelegenheitsanwender leicht verständlich .*\.txtist, richtet sich das Analoge eher an erfahrene Benutzer / Programmierer, ganz zu schweigen von ^.*\.txt$...

jlliagre
quelle
2
Ein weiterer Grund für das Warum: Geschwindigkeit. Reguläre Ausdrücke sind langsamer: pastebin.com/3iNCgkE3
Manatwork
3
*.txtist nicht gleich .*\.txt, es ist (meistens) gleich, .*\.txt$weil es nach dem .txt(zumindest unter der Annahme eines vernünftigen Dateinamensglobbing) nichts mehr geben kann . Vielleicht sogar ^.*\.txt$etwas je nach Nutzung. Bewährt sich Ihr Standpunkt?
ein CVn