Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have 300k+ jpg files in the same directory. Files are like:


I need to batch resize saving the resized images in the same directory with a prefix th_ in filename like


all inside /covers

The following works but it overwrites the source files

$ find thumbs -type f -name "*.jpg" | xargs mogrify -resize 75x75

so I have to copy all the images into a new dir (/covers/thumbs) and then run the batch and then move all the files back to /covers

share|improve this question
up vote 5 down vote accepted

From the manual:

Mogrify overwrites the original image file, whereas, convert(1) writes to a different image file.

You can do:

find convert -type f -name '*.jpg' -execdir convert {} -resize 75x75 th_{} \;

This will probably be the most efficient if you have a large number of files.

In general, for various reasons it is a rather bad idea to pipe the output of find to xargs, unless you use the following pattern, which the GNU and BSD find variants support: find … -print0 | xargs -0 …

If you want to use shell-only commands, you can loop over the files like so:

for image in convert/*.jpg; do convert "$image" -resize 75x75 "$(dirname $image)/th_$(basename $image)"; done

That's the easiest (and safest) you can get, without having to resort to external commands. You will, however need to split up path and filename and insert the prefix in between. If you're already in the same folder, this is much easier:

for i in *.jpg; do convert "$i" -resize 75x75 "th_$i"; done

A universal and shorter solution with Zsh:

for i (convert/*.jpg) convert "$i" -resize 75x75 "${i:h}/th_${i:t}"    
share|improve this answer
hi there! My files are NOT in the /thumbs folder but in /covers. So I assume the command line will become: for image in covers/*.jpg; do convert "$image" -resize 75x75 "th_$(basename $image)"; done Will this save in the same dir as the master files? Correct? Tnx! – Gabriele May 19 '13 at 19:31
I tried with a sample dir/files. It didn't work – Gabriele May 19 '13 at 19:37
Sorry, wrong folder there. See my latest update. If you want the command to work with any arbitrary folder, then you need to split up the path between dirname and basename and insert the prefix there. The following would be easier, if you're already in the folder: for i in *.jpg; do convert "$i" -resize 75x75 "th_$i"; done. – slhck May 19 '13 at 19:39
test with 3 images was succesful. I'll run it in the main dir with 300K+ files and I'll get back here. Thanks slhck! – Gabriele May 19 '13 at 19:43
If your argument list ends up too long (because of 300K+ files), try the variant using find with execdir which I added to my answer above. – slhck May 19 '13 at 19:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .