Qual é a diferença entre “* .pl” e * .pl no grep? Por que as cotações mudam 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ê?

    
por Jim 07.07.2013 / 23:24

2 respostas

17

O * (estrela ou asterisco) é 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 principais. Consulte o manual sobre a 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 ao comando verbatim.

Exemplos explicados. O citado:

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

Aqui grep receberá a opção --include com o argumento *.pl . Essa é a cadeia de 4 caracteres com o caractere * como primeiro caractere. O que grep faz com essa sequência é de até grep . Nesse caso, --include significa considerar apenas os arquivos que correspondem ao padrão *.pl .

AFAIK nos bastidores gnu grep usa o mesmo padrão que combina lib como gnu bash.

O não citado:

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

Aqui, o shell primeiro expandirá o padrão *.pl para todos os nomes de arquivos terminados em .pl . Suponha que haja os arquivos foo.pl , bar.pl e baz.pl . Depois de expandir a linha de comando, é assim:

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

Aqui grep receberá a opção --include com o argumento foo.pl , seguido pelas opções bar.pl e baz.pl . --include foo.pl significa 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 arquivo denominado foo.pl .

As opções bar.pl e baz.pl significam que o grep também irá procurar nesses arquivos, mas como eles não correspondem ao padrão foo.pl , eles serão ignorados.

    
por 07.07.2013 / 23:29
6

A diferença é que, se você não citar o padrão ( *.pl ), ele será expandido pelo shell. Por exemplo, se você executar o grep em um diretório que contenha um arquivo chamado foo.pl , pois o *pl é expandido pelo shell, o que o grep realmente vê é:

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

Como você diz para incluir apenas foo.pl , ele só pesquisará esse arquivo.

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

 grep "string" . -r --include *pl
    
por 07.07.2013 / 23:32