Was ist der Unterschied zwischen "* .pl" und * .pl in grep? Warum ändert das Zitieren das Ergebnis?

10

Was ist der Unterschied zwischen:
grep "string" . -r --include *.pl

und

grep "string" . -r --include "*.pl"

Letzteres enthält Dateien in Unterverzeichnissen, während Ersteres nicht. Warum?

Jim
quelle
Der Unterschied liegt nicht darin grep; es ist in der Schale. grepsieht nie die Zitate.
Wildcard

Antworten:

17

Der *(Stern oder Stern) ist ein Sonderzeichen, das (normalerweise) von der Shell interpretiert wird, bevor sie den Befehl erhält. Es wird (normalerweise) auf alle Dateinamen mit Ausnahme derjenigen mit führenden Punkten erweitert. Weitere Informationen finden Sie im Bash-Handbuch zum Pattern Matching .

Wenn der Stern in Anführungszeichen gesetzt wird, wird er von der Shell nicht interpretiert und dem Befehl wörtlich übergeben.


Beispiele erklärt. Der Zitierte:

grep "string" . -r --include "*.pl"

Hier greperhalten Sie die Option --includemit dem Argument *.pl. Das ist die 4-stellige Zeichenfolge mit dem *Zeichen als erstem Zeichen. Was grepmit dieser Zeichenfolge zu tun hat, liegt ganz bei Ihnen grep. In diesem Fall --includebedeutet dies, nur Dateien zu berücksichtigen, die dem Muster entsprechen *.pl.

AFAIK hinter den Kulissen gnu grep verwendet das gleiche Muster, das lib entspricht wie gnu bash.

Der nicht zitierte:

grep "string" . -r --include *.pl

Hier erweitert die Shell das Muster zunächst *.plauf alle Dateinamen, die auf enden .pl. Angenommen , es sind die Dateien foo.pl, bar.plund baz.pl. Nach dem Erweitern sieht die Befehlszeile folgendermaßen aus:

grep "string" . -r --include foo.pl bar.pl baz.pl

Hier greperhalten Sie die Option --includemit dem Argument foo.pl, gefolgt von den Optionen bar.plund baz.pl. --include foo.plbedeutet, nur Dateien zu berücksichtigen, die dem Muster entsprechen foo.pl. Da das Muster keine Platzhalter enthält, ist die einzige übereinstimmende Datei die benannte Datei foo.pl.

Die Optionen bar.plund baz.plMittel grep suchen auch in diesen Dateien, aber da sie nicht mit dem Muster übereinstimmen, foo.plwerden sie ignoriert.

Lesmana
quelle
Dies ist eine großartige Beobachtung. Ich habe mich immer gefragt, warum es grep -rinkonsistent schien, aber ich habe nie bemerkt, dass es nur war, wenn ich ein verwendet habe *.
j883376
6

Der Unterschied besteht darin, dass das Muster ( *.pl) durch die Shell erweitert wird, wenn Sie es nicht zitieren . Wenn Sie beispielsweise Ihre grepDatei in einem Verzeichnis ausführen , das eine aufgerufene Datei enthält foo.pl, da die *plvon der Shell erweitert wird, wird greptatsächlich Folgendes angezeigt:

grep "string" . -r --include foo.pl

Da Sie angeben, dass es nur enthalten soll foo.pl, wird nur diese eine Datei durchsucht.

Wenn Sie Ihr Muster zitieren, wird es von der Shell nicht erweitert und greperhält den richtigen Befehl, nämlich

 grep "string" . -r --include *pl
terdon
quelle
peoplwird nicht erweitert durch *.pl.
Unxnut
@unxnut guter Punkt, Antwort bearbeitet.
Terdon