views:

305

answers:

7

Hi all,

I'm looking for a solution to convert a set of files using the terminal and the command "convert" under linux. I can use "convert" for each file:

convert -quality 85 file.jpg file.jpg

But i'm looking for something like:

for each jpg do
  convert -quality 85 $file $file
end

Can someone tell me, which command i can use?

+10  A: 
for i in *.jpg; do
   convert ... $i $i
done

should do it. That will work for sh/bash/zsh etc. It assumes that all your *.jpg files are in the current directory. Otherwise, replace *.jpg with an appropriate find invocation e.g.

for i in `find . -name "*.jpg" -print`; do

Note the backticks. These indicate that the enclosed command should be executed, and the results returned to the invoking structure (in this case, the for loop)

If you're using zsh, then you can do

for i in **/*.jpg; do

to search subdirectories in your wildcard, and qualify these further using advanced zsh wildcard syntax. I'm not sure what facilities bash offers in this area, however.

Brian Agnew
thank you very much
cupakob
Don't forget xargs. Not necessarily as powerful as a for loop, but often handy to know it's available: find -name '*.jpg' | xargs -l -i convert -quality 85 {} {}
opello
ooh! I didn't know you could do that with xargs! I feel smarter.
sheepsimulator
or you can do it even without the xargs via: find . -name "*.jpg" -exec convert -quality 85 {} \:
rasjani
Bash 4.0, once you enable the globstar shell option with `shopt -s globstar`, treats **/*.jpg just like Zsh does.
ephemient
Instead of the backticks you can use $(...) which is IMHO a little bit clearer.
unbeknown
+4  A: 

If you're using Bash, you could do something like the following:

$ for f in `ls path/to/jpegs/*.jpg`; do convert -quality 85 $f $f; done

That will loop through all the JPEGs in a given directory and convert them.

If you're not using Bash, your shell may have a similar for-loop syntax; check the man pages.

mipadi
Always good to exhibit the single line version.
dmckee
+1  A: 

I'd write a shell script. If your'e unfamiliar with shell programming, see this page.

#!/bin/sh

for arg in `ls *.jpg`
do
    convert -quality 85 $arg $arg
done
sheepsimulator
'$files $files', not '$arg $arg' or the other way around maybe?
Joakim Elofsson
@Joakim Elofsson - Good catch, thanks!
sheepsimulator
A: 

What about? :

find [-maxdepth 1] -iname "*.jpg" -exec mogrify -quality 85 {} \;
  • optional -maxdepth 1 to operate on current directory only (no subdir.)
  • ImageMagick comes with mogrify, which modifies files in place.
coredump
+1  A: 

If you have a multicore machine, you can get some real speed by doing them in parallel:

mkdir -p converted
find -iname '*.jpg' -print0 | xargs -0 -P<number of cores> -n1 -Ifoo convert -quality 85 foo converted/foo
dlowe
A: 
find . -name '*.jpg' -exec convert -quality 85 {} {} \;
arsane
+2  A: 

Instead of converting each file by overwriting itself, you can use its sister command mogrify, that edits the file in place. Also, both commands have built-in globbing, so they can modify all images in a single call, which is faster than running the program once per image. See ImageMagick Command Line Processing for more information.

So this will do:

mogrify '*.jpg' -quality 85
Roberto Bonvallet