Linux – How to run mogrify, but prefix the filename

imagemagicklinux

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

/covers    
0788862281217.jpg
0788863155104.jpg
7888311516341.jpg
7888370920479.jpg
7888497074277.jpg

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

th_0788862281217.jpg
th_0788863155104.jpg
th_7888311516341.jpg
th_7888370920479.jpg
th_7888497074277.jpg

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

Best Answer

  • From the manual:

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

    You can do:

    find ./covers -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 ./covers/*.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 (./covers/*.jpg) convert "$i" -resize 75x75 "${i:h}/th_${i:t}"    
    
  • Related Question