Copiando arquivos recursivamente com espaços

3

No momento, tenho um conjunto de arquivos na forma de:

/dir one/a picture.jpg
/dir two/some picture.jpg

O que eu quero fazer é copiar e alterar o final para -fanart.jpg para o nome do arquivo para:

/dir one/a picture.jpg
        /a picture-fanart.jpg
/dir two/some picture.jpg
        /some picture-fanart.jpg

Consegui fazê-lo funcionar para a situação em que não há espaços:

% for i in 'find . -name "*.jpg"'; do cp $i "${i%.*}"-fanart.jpg ;done;

mas eu faço funcionar onde há espaços.

    
por user3217458 21.01.2014 / 04:24

2 respostas

3

A substituição de comandos ( '...' ou $(...) ) é dividida em caractere de nova linha, tabulação e espaço (não apenas nova linha) e geração de nome de arquivo (globbing) é executada em cada palavra resultante dessa divisão. Esse é o operador split + glob . Você poderia melhorar as coisas configurando $IFS para nova linha e desativando globbing, mas aqui, o melhor é escrever da maneira correta:

find . -name "*.jpg" -type f -exec sh -c '
  for i do
    cp "$i" "${i%.*}-fanart.jpg"
  done' sh {} +

Você também pode usar pax para isso:

pax -rws'/\.jpg$/-fanart&/' -s'/.*//' . .

Ou zmv do zsh :

autoload zmv
zmv -QC '(**/)(*)(.jpg)(D.)' '$1$2-fanart$3'
    
por 21.01.2014 / 08:19
2

A expansão do Word é executada durante a expansão de substituições de comandos sem aspas, e é por isso que isso não funciona.

Se você tem bash4 +, use globstar:

shopt -s globstar
for file in **/*.jpg; do
    cp -- "$file" "${file%.*}-fanart.jpg"
done
    
por 21.01.2014 / 04:29