De que maneira os parâmetros de cotação para 'find' são importantes? [duplicado]

0

Ao procurar por arquivos txt, eu corro este comando:

find . -name "*.txt" -print

Isso me dá uma lista de todos os arquivos de texto abaixo do diretório atual.

No entanto, find . -name *.txt -print me apresenta o seguinte erro: find: paths must precede expression: mein.txt

Este é o comportamento geralmente esperado? Que diferença as aspas fazem?

    
por Abdi 15.02.2017 / 22:11

2 respostas

2

Dentro de um token que não é citado, é o seu shell que executará expansão, não o comando que você está executando.

Isso significa que, quando você insere find . -name "*.txt" -print , find recebe o literal *.txt como um dos seus parâmetros e usa esse padrão como o argumento para sua opção -name , que corresponderá os nomes dos arquivos encontrados antes de aplicar -print .

Por outro lado, quando você digita find . -name *.txt -print , o shell transmite a versão expandida de *.txt para localizar. Vários casos são possíveis:

  1. Não há arquivos correspondentes a *.txt no diretório atual: find recebe um literal *.txt (assumindo configurações padrão de bash);

  2. existe exatamente um arquivo correspondente a *.txt no atual diretório; digamos que seja a.txt : find recebe esse nome de arquivo, e corresponde a todos os arquivos chamados a.txt encontrados a partir do atual diretório;

  3. vários arquivos correspondem a *.txt no diretório atual (isso aparece para ser o seu caso): -name recebe o primeiro como seu parâmetro, e os outros são mais parâmetros de caminho para encontrar, que reclama sobre não receber todos os caminhos antes da expressão.

Esse é o comportamento esperado.

Vamos supor a seguinte hierarquia de arquivos:

.
├── a.txt
├── b.txt
├── c.txt
└── foo
    ├── a.txt
    ├── b.txt
    └── c.txt

Os parâmetros reais encontrados no caso podem ser observados substituindo a chamada para localizar com printf '%s\n' , que será impressa cada argumento expandido em sua própria linha:

$ printf '%s\n' . -name "*.txt" -print
.
-name
*.txt
-print

$ printf '%s\n' . -name *.txt -print
.
-name
a.txt
b.txt
c.txt
-print

Como você pode ver, a segunda invocação que você postou é equivalente, dados os arquivos existentes, para find . -name a.txt b.txt c.txt -print .

    
por 15.02.2017 / 22:24
1

Esse é o comportamento esperado - é conhecido como "shell globbing". Sem as aspas, o *.txt é expandido pelo shell para passar a lista inteira de arquivos que correspondem a essa expressão para o comando find . Ao circundá-lo entre aspas, você diz ao shell para passar a string literal *.txt para find . Você pode obter a mesma proteção usando outros métodos de escape, como find . -name \*.txt ou find . -name '*.txt' .

    
por 15.02.2017 / 22:16