Quelle est la différence entre «* .pl» et * .pl dans grep? Pourquoi la cotation change-t-elle le résultat?

10

Quelle est la différence entre:
grep "string" . -r --include *.pl

et

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

Ce dernier inclut des fichiers dans les sous-répertoires tandis que le premier ne l'est pas. Pourquoi?

Jim
la source
La différence n'est pas dans grep; c'est dans la coquille. grepne voit jamais les citations.
Wildcard

Réponses:

17

*( L' étoile ou l'astérisque) est un caractère spécial qui est (généralement) interprété par le shell avant qu'il ne reçoive la commande. Il est (généralement) étendu à tous les noms de fichiers à l'exception de ceux avec des points de tête. Voir le manuel bash sur la correspondance de modèles pour plus d'informations.

S'il est placé entre guillemets, l'étoile ne sera pas interprétée par le shell et sera donnée à la commande mot pour mot.


Exemples expliqués. Celui cité:

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

Ici greprecevra l'option --includeavec l'argument *.pl. Il s'agit de la chaîne de 4 caractères avec le *caractère comme premier caractère. Ce que grepfait cette chaîne est entièrement à la hauteur grep. Dans ce cas, cela --includesignifie de ne considérer que les fichiers correspondant au modèle *.pl.

AFAIK dans les coulisses gnu grep utilise le même motif correspondant à lib que gnu bash.

Celui non cité:

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

Ici, le shell étendra d'abord le modèle *.plà tous les noms de fichiers se terminant par .pl. Supposons qu'il y ait les fichiers foo.pl, bar.plet baz.pl. Après avoir développé la ligne de commande ressemble à ceci:

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

Ici greprecevra l'option --includeavec l'argument foo.pl, suivie des options bar.plet baz.pl. --include foo.plsignifie considérer uniquement les fichiers correspondant au modèle foo.pl. Puisqu'il n'y a pas de caractères génériques dans le modèle, le seul fichier correspondant qui sera le fichier nommé foo.pl.

Les options bar.plet les baz.plmoyens de grep rechercheront également dans ces fichiers, mais comme ils ne correspondent pas au modèle, foo.plils seront ignorés.

lesmana
la source
Ceci est une grande observation. Je me suis toujours demandé pourquoi cela grep -rsemblait incohérent, mais je n'ai jamais remarqué que c'était seulement lorsque j'utilisais un *.
j883376
6

La différence est que si vous ne citez pas le motif ( *.pl), il est développé par le shell. Par exemple, si vous exécutez votre grepdans un répertoire qui contient un fichier appelé foo.pl, puisque le *plest développé par le shell, ce grepqui apparaît en réalité est:

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

Puisque vous lui dites de l'inclure uniquement, foo.plil ne recherchera que dans ce fichier.

Si vous citez votre modèle, le shell ne le développera pas et grepobtiendra la commande correcte, à savoir

 grep "string" . -r --include *pl
terdon
la source
peoplne sera pas développé par *.pl.
unxnut
@unxnut bon point, réponse modifiée.
terdon