confuso sobre aspas duplas

4

Eu aprendi quando eu uso o comando, citando em dobro tratar todas as coisas como caractere, exceto $, ', \.

Mas, quando o comando use como find -type f -name "*.jpg" *.jpg está entre aspas duplas. Então, isso significa que queremos tratar * e . como apenas um caractere. Portanto, o comando find deve gerar um arquivo regular que tenha o nome *.jpg , conforme indicado, e não a expansão do nome do caminho implementada.

Se quisermos fazer a expansão do nome do caminho, acho que tenho que digitar o comando find -type f -name *.jpg (sem aspas duplas).

Mas o resultado é o mesmo. Por que usar aspas duplas neste comando?

    
por A.Cho 19.02.2016 / 17:41

2 respostas

5

Há uma sutileza de como funciona a expansão de caractere curinga. Mude para um diretório que não contenha arquivos .jpg e digite

echo *.jpg

e irá produzir

*.jpg

Em particular, a string * .jpg não é modificada. Se, no entanto, você mudar para um diretório contendo arquivos .jpg, por exemplo, suponha que temos dois arquivos: image1.jpg e image2.jpg, então o comando echo * .jpg não produzirá

image1.jpg image2.jpg

e o * .jpg é expandido.

Se você digitar

find . -name *.jpg

e não há arquivos .jpg no diretório em que você está quando digita isso, então o find irá receber os argumentos ".", "-name" e "* .jpg". Se, no entanto, você digitar esse comando em um diretório contendo arquivos .jpg, digamos image1.jpg e image2.jpg, então, find receberá os argumentos ".", "-Name", "image1.jpg" e "image2.jpg". ", portanto, será executado o comando

find . -name image1.jpg image2.jpg

e encontrar vai reclamar. O que pode ser realmente confuso se você omitir as aspas é se houver um único arquivo .jpg (digamos image1.jpg). Em seguida, a expansão de curinga resultará em

find . -name image1.jpg

e o comando find encontrará todos os arquivos cujo nome de base é image1.jpg.

Além disso: Isso leva a um idioma bash útil para ver se algum arquivo corresponde a um determinado padrão:

if [ "$(echo *.jpg)" = "*.jpg" ]; then
    # *.jpg has no matches
else
    # *.jpg has matches
fi

embora seja avisado que isso não funcionará se houver um arquivo chamado '* .jpg' no diretório atual. Para ser mais impermeável, você pode fazer

if [ "$(echo *.jpg)" = "*.jpg" ] && [ ! -e "*.jpg" ]; then
    # *.jpg has no matches
else
    # *.jpg has matches
fi

(Embora não seja diretamente relevante para a pergunta, eu adicionei isso, pois ilustra alguns dos aspectos de como a expansão de caractere curinga funciona.)

    
por 19.02.2016 / 17:56
4

Você precisa escapar do asterisco no padrão de nome porque find deseja fazer sua própria expansão glob em todos os vários diretórios pesquisados. Se deixado sem escape, o * seria expandido pelo shell e apenas para o diretório atual. Isso provavelmente renderia uma invocação ilegal de find .

    
por 19.02.2016 / 17:45