¿Cuál es la diferencia entre "* .pl" y * .pl en grep? ¿Por qué las citas cambian el resultado?

10

Cuál es la diferencia entre:
grep "string" . -r --include *.pl

y

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

El último incluye archivos en subdirectorio, mientras que el primero no. ¿Por qué?

Jim
fuente
La diferencia no está en grep; Está en el caparazón. grepNunca ve las citas.
Comodín el

Respuestas:

17

La *(estrella o asterisco) es un carácter especial que (generalmente) es interpretado por el shell antes de recibir el comando. Se expande (generalmente) a todos los nombres de archivo, excepto aquellos con puntos iniciales. Consulte el manual de bash sobre coincidencia de patrones para obtener más información.

Si se coloca entre comillas, la estrella no será interpretada por el shell y se le dará al comando textualmente.


Ejemplos explicados. El citado:

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

Aquí greprecibirá la opción --includecon el argumento *.pl. Esa es la cadena de 4 caracteres con el *carácter como primer carácter. Lo que grephace con esa cadena depende completamente grep. En este caso, --includesignifica considerar solo los archivos que coinciden con el patrón *.pl.

AFAIK detrás de escena gnu grep usa el mismo patrón que coincide con lib que gnu bash.

El no citado:

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

Aquí el shell primero expandirá el patrón *.pla todos los nombres de archivo que terminen en .pl. Supongamos que existen los archivos foo.pl, bar.ply baz.pl. Después de expandir la línea de comando se ve así:

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

Aquí greprecibirá la opción --includecon el argumento foo.pl, seguido de las opciones bar.ply baz.pl. --include foo.plsignifica considerar solo los archivos que coinciden con el patrón foo.pl. Como no hay comodines en el patrón, la única coincidencia de archivo será el nombre del archivo foo.pl.

Las opciones bar.ply baz.plmedios grep también buscarán en esos archivos, pero como no coinciden con el patrón foo.pl, se ignorarán.

lesmana
fuente
Esta es una gran observación. Siempre me pregunté por qué grep -rparecía inconsistente, pero nunca me di cuenta de que era solo cuando usaba a *.
j883376
6

La diferencia es que si no cita el patrón ( *.pl), el shell lo expande. Por ejemplo, si ejecuta su grepen un directorio que contiene un archivo llamado foo.pl, ya que *plel shell lo expande, lo que greprealmente ve es:

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

Como le dice que solo incluya foo.pl, solo buscará en ese archivo.

Si cita su patrón, el shell no lo expandirá y grepobtendrá el comando correcto, es decir

 grep "string" . -r --include *pl
terdon
fuente
peoplno se expandirá por *.pl.
unxnut
@unxnut buen punto, respuesta editada.
terdon