Copying recursively files with spaces

command linecp

At the moment I have a set of files of the form of:

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

What I want to do is copy and change the end to -fanart.jpg to the filename to:

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

I've managed to get it working for the situation where there are no spaces:

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

but I to get it working where there are spaces.

Best Answer

Command substitution (`...` or $(...)) is split on newline, tab and space character (not only newline), and filename generation (globbing) is performed on each word resulting of that splitting. That's the split+glob operator. You could improve things by setting $IFS to newline and disable globbing, but here, best is to write it the proper way:

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

You could also use pax for that:

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

Or zsh's zmv:

autoload zmv
zmv -QC '(**/)(*)(.jpg)(D.)' '$1$2-fanart$3'
Related Question