using 'find' and 'xargs' to manipulate photos with ImageMagick

I have
/dir/1.jpg
/dir/dir2/2.jpg
/3.jpg

I want to:
mkdir OUTPUT
find . -type f -print0 | xargs -0 -n 1 -I file convert -resize ‘800x800>’ ./OUTPUT/file

But it doesn’t always work, because it wants to save result in OUTPUT/dir/dir2/2.jpg (for example).

How can I make sure that all the output images are not put into subdirectories underneath OUTPUT. I tried basename file but it doesn’t do what I want. Ideas?

Since you are asking xargs to consume only one argument at a time, it’s a waste to call it. Try something like this

find . -type f | while read f
do
  convert -resize '800x800>' "$f" "OUTPUT/`basename $f`"
done

$OUTPUT=dir
mkdir ./$OUTPUT
find . -type f -print0 | xargs -0 -n 1 -I file convert -resize ‘800x800’ > ./$OUTPUT/$(basename $file)

I am just trying to get the exact syntax that you are using and say that does not work. Is the above example correct or can you retype the line as it is used?

As for your signature, I think that open source drivers for nVidia graphic cards would be a good thing, but nVidia does release their drivers free of charge to the public, they are updated very often, their support for Linux has been the best so far and they are trying to protect their hardware from prying eyes. Right or wrong as you see it, they have the right to do the things they are doing. It light of the total picture, I would be unable to sign such a petition against nVidia, but good luck in your cause.

Thank You,

If OUTPUT is really under ‘.’ you’ll need to -prune OUTPUT, else you could recurse a while ;). It’s usually easier to put the output somewhere else and then move it back.

The petition is right. The signature is wrong. It’s not about ‘free’ but about ‘open source’ drivers. Unfortunately (or fortunately ), becoming free is more likely the consequence of beeing open. Nvidia’s proprietary Linux drivers are not the worse of all proprietary drivers, that’s true and most Linux users have noticed that. But what about Nvidia’s support for BSD? IMHO Linux users should stop believing they are the only open source users in the world. What BSD users wanted was not support but informations, so it would become possible to write better “transparent” drivers for Nvidia cards. Using a closed source driver on a Unix kernel is a security matter and will never happen under security oriented OSs like OpenBSD. I agree with that petition but didn’t sign it because such petitions never work. OpenBSD users and Linux sysadmins concerned about security issues (they are some) simply don’t buy Nvidia products (as far as they can avoid it).

Or collect the list of files first before processing.

find . -type f > listoffiles
while read f
do
  convert -resize '800x800>' "$f" "OUTPUT/`basename $f`"
done < listoffiles
  • save all results in current directory
eval `find . -name "*.jpg" | awk -F "/" '{ printf "convert -resize \"800x800&gt;\" %s %s; ", $0, $NF }'`
  • save alle results in directory OUPTUT (provided it exists!)
eval `find . -name "*.jpg" | awk '{ DEST=$0 ; sub(/./,"",DEST) ; printf "convert -resize \"800x800&gt;\" %s OUTPUT%s; ", $0, DEST }'`

Try these commands without ‘eval’ and the backquotes first to see ig it’s going to do what you want.

But if you apply the command above to too many files, at some point the command line will get too long. In such a case, don’t use eval ``, replace the semicolon in the awk string (the one after the last %s) with
, redirect to a file ( > somefile ) and execute that file as a script.

Well, if the resulting files shall keep the same path relative to OUTPUT, you’ll get errors while using the second command I posted before, because the subdirectories don’t exist. You should create them first, for example with a command like the following:

mkdir -p `find . -name "*.jpg" | awk  -F "/" '{ $1="" ; $NF="" ; gsub(/ /,"/",$0); print "OUTPUT"$0 }' | sort -u` 

Excellent! ‘while’ is the ticket indeed. Thanks to all for your suggestions.