Qual é a diferença entre "* .pl" e * .pl no grep? Por que a cotação altera o resultado?

10

Qual é a diferença entre:
grep "string" . -r --include *.pl

e

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

O último inclui arquivos em subdiretórios, enquanto o primeiro não. Por quê?

Jim
fonte
A diferença não está presente grep; está na concha. grepnunca vê as aspas.
Curinga

Respostas:

17

O *(asterisco ou estrela) é um caractere especial que é (geralmente) interpretado pelo shell antes de receber o comando. É (geralmente) expandido para todos os nomes de arquivos, exceto aqueles com pontos iniciais. Consulte o manual do bash sobre correspondência de padrões para obter mais informações.

Se colocada entre aspas, a estrela não será interpretada pelo shell e será dada literalmente ao comando.


Exemplos explicados. O citado:

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

Aqui grepreceberá a opção --includecom o argumento *.pl. Essa é a sequência de 4 caracteres com o *caractere como primeiro caractere. O que grepfaz com essa string é inteiramente de responsabilidade grep. Nesse caso, --includesignifica considerar apenas os arquivos que correspondem ao padrão *.pl.

Nos bastidores do AFAIK, o gnu grep usa o mesmo padrão que corresponde à lib que o gnu bash.

O não citado:

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

Aqui, o shell primeiro expandirá o padrão *.plpara todos os nomes de arquivos terminados em .pl. Suponha que existem os arquivos foo.pl, bar.ple baz.pl. Após expandir a linha de comando, fica assim:

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

Aqui grepreceberá a opção --includecom o argumento foo.pl, seguido pelas opções bar.ple baz.pl. --include foo.plsignifica considerar apenas os arquivos que correspondem ao padrão foo.pl. Como não há curingas no padrão, o único arquivo correspondente será o nome do arquivo foo.pl.

As opções bar.ple os baz.plmeios grep também procurarão nesses arquivos, mas como eles não correspondem ao padrão foo.pl, serão ignorados.

lesmana
fonte
Esta é uma ótima observação. Eu sempre me perguntei por que grep -rparecia inconsistente, mas nunca percebi que era apenas quando eu usava um *.
J883376
6

A diferença é que, se você não citar o padrão ( *.pl), ele é expandido pelo shell. Por exemplo, se você executá-lo grepem um diretório que contém um arquivo chamado foo.pl, uma vez que o *plé expandido pelo shell, o que greprealmente vê é:

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

Como você diz para incluir apenas, foo.plele pesquisará apenas esse arquivo.

Se você citar seu padrão, o shell não o expandirá e obterá grepo comando correto, a saber

 grep "string" . -r --include *pl
terdon
fonte
peoplnão será expandido por *.pl.
unxnut
@ unxnut bom ponto, resposta editada.
terdon