Qual è la differenza tra “* .pl” e * .pl in grep? Perché la quotazione cambia il risultato?


10

Qual è la differenza tra:
grep "string" . -r --include *.pl

e

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

Quest'ultimo include i file in sottodiretti mentre il primo no. Perché?


La differenza non è in grep; è nel guscio. grepnon vede mai le virgolette.
Wildcard l'

Risposte:


17

La *(stella o asterisco) è un carattere speciale che viene (di solito) interpretato dalla shell prima che gli venga dato il comando. Viene (di solito) espanso a tutti i nomi di file tranne quelli con punti iniziali. Vedere il manuale di bash sulla corrispondenza dei motivi per ulteriori informazioni.

Se inserito tra virgolette, la stella non verrà interpretata dalla shell e viene data al comando alla lettera.


Esempi spiegati. Quello citato:

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

Qui grepriceverà l'opzione --includecon l'argomento *.pl. Questa è la stringa di 4 caratteri con il *carattere come primo carattere. Ciò che grepfa con quella stringa dipende interamente da grep. In questo caso --includesignifica considerare solo i file corrispondenti allo schema *.pl.

AFAIK dietro le quinte gnu grep usa lo stesso modello che combina lib di gnu bash.

Quello non citato:

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

Qui la shell espande prima il modello *.pla tutti i nomi di file che terminano con .pl. Supponiamo che ci siano i file foo.pl, bar.ple baz.pl. Dopo aver espanso la riga di comando appare così:

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

Qui grepriceverà l'opzione --includecon l'argomento foo.pl, seguita dalle opzioni bar.ple baz.pl. --include foo.plsignifica considerare solo i file corrispondenti allo schema foo.pl. Poiché non ci sono caratteri jolly nel modello, l'unico file corrispondente che sarà il file denominato foo.pl.

Le opzioni bar.ple i baz.plmezzi che grep ricercherà anche in quei file, ma poiché non corrispondono allo schema foo.plverranno ignorati.


Questa è una grande osservazione. Mi sono sempre chiesto perché grep -rsembrava incoerente, ma non ho mai notato che era solo quando ho usato un *.
j883376,

6

La differenza è che se non citate il pattern ( *.pl) viene espanso dalla shell. Ad esempio, se esegui il tuo grepin una directory che contiene un file chiamato foo.pl, poiché *plviene espanso dalla shell, ciò che grepeffettivamente vede è:

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

Dal momento che gli dici di includere solo foo.pl, cercherà solo attraverso quel file.

Se citate il vostro modello, la shell non lo espanderà e grepotterrà il comando corretto, vale a dire

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

peoplnon verrà espanso da *.pl.
Unxnut

@unxnut buon punto, risposta modificata.
terdon
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.