Argumentos Subshell no parâmetro -exec para find (1)

6

Por que não

find . -type f -exec echo $(file={}; echo ${file:0:5}) \;

dê os cinco primeiros caracteres do arquivo, enquanto isso funciona:

find . -type f -exec bash -c 'echo ${1:0:5}' funcname {} \;

Plano de fundo :

Estou tentando converter em lotes uma árvore cheia de imagens para miniaturas, e quero renomeá-las rapidamente adicionando '_thumb' no final do nome do arquivo, mas antes da extensão. Este processo de renomeação é fácil para um arquivo:

file='I am a picture.jpg'
mv \"$file\" \"${file%\.*}_thumb.${file##*\.}\"

(a segunda linha expande para mv "I am a picture.jpg" "I am a picture_thumb.jpg" )

mas quando tento encapsular esse comando no parâmetro -exec de find(1) não consigo manipular o nome do arquivo dado por find (exemplos simplificados):

find . -type f -exec ${{}:0:5}) \;

bash: ${{}:0:5}: bad substitution

Usando um subshell, fico um pouco mais longe:

find . -type f -exec echo $(file={}; echo ${file:0:5}) \;

isto ecoa o nome do arquivo, mas não executa a manipulação da string por algum motivo.

Eu finalmente encontrei a solução em esta postagem SO :

find . -type f -exec bash -c 'echo ${1:0:5}' funcname {} \;

mas não entendo por que isso funcionaria quando a construção $(...) não funciona.

    
por Tim 09.04.2012 / 15:50

1 resposta

6

exec faz o que diz: usa exec() . Ele não envolve um shell a menos que seja informado para ( -exec bash ... ), e se ele ainda ainda precisar de aspas simples para impedir que o shell interativo interprete as interpolações variáveis. (O shell não é mágico e não sabe que você pretendia que aqueles fossem interpolados por outra coisa.)

Por exemplo, quando você usa o seguinte comando:

find . -type f -exec echo $(file={}; echo ${file:0:5}) \;

seu shell primeiro executa a substituição do processo executando $(file={}; echo ${file:0:5}) , que simplesmente gera {} , então executa o comando final:

find . -type f -exec echo {} \;
    
por 09.04.2012 / 15:54

Tags