Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add prefix to all images (recursive)

I have a folder with more than 5000 images, all with JPG extension.

What i want to do, is to add recursively the "thumb_" prefix to all images.

I found a similar question: Rename Files and Directories (Add Prefix) but i only want to add the prefix to files with the JPG extension.

like image 494
MadisonFord Avatar asked May 26 '11 14:05

MadisonFord


2 Answers

One of possibly solutions:

find . -name '*.jpg' -printf "'%p' '%h/thumb_%f'\n" | xargs -n2  echo mv

Principe: find all needed files, and prepare arguments for the standard mv command.

Notes:

  • arguments for the mv are surrounded by ' for allowing spaces in filenames.
  • The drawback is: this will not works with filenames what are containing ' apostrophe itself, like many mp3 files. If you need moving more strange filenames check bellow.
  • the above command is for dry run (only shows the mv commands with args). For real work remove the echo pretending mv.

ANY filename renaming. In the shell you need a delimiter. The problem is, than the filename (stored in a shell variable) usually can contain the delimiter itself, so:

mv $file $newfile         #will fail, if the filename contains space, TAB or newline
mv "$file" "$newfile"     #will fail, if the any of the filenames contains "

the correct solution are either:

  • prepare a filename with a proper escaping
  • use a scripting language what easuly understands ANY filename

Preparing the correct escaping in bash is possible with it's internal printf and %q formatting directive = print quoted. But this solution is long and boring.

IMHO, the easiest way is using perl and zero padded print0, like next.

find . -name \*.jpg -print0 | perl -MFile::Basename -0nle 'rename $_, dirname($_)."/thumb_".basename($_)'

The above using perl's power to mungle the filenames and finally renames the files.

like image 175
jm666 Avatar answered Oct 05 '22 23:10

jm666


Beware of filenames with spaces in (the for ... in ... expression trips over those), and be aware that the result of a find . ... will always start with ./ (and hence try to give you names like thumb_./file.JPG which isn't quite correct).

This is therefore not a trivial thing to get right under all circumstances. The expression I've found to work correctly (with spaces, subdirs and all that) is:

find . -iname \*.JPG -exec bash -c 'mv "$1" "`echo $1 | sed \"s/\(.*\)\//\1\/thumb/\"`"' -- '{}' \;

Even that can fall foul of certain names (with quotes in) ...

like image 24
FrankH. Avatar answered Oct 06 '22 00:10

FrankH.