I have a deep directory structure, with a large number of files (about 1M). I'd like to execute a command against each. (In my case the files are pngs which I'd like to run optipng against.)
I've tried this:
find . -name *.png | xargs sudo optipng -o2
but am getting the error argument list too long
.
I'm assuming that xargs should be able to handle this, and that there must be a problem with my syntax.
Do the exec directly with find rather than via xargs.
Using sudo as command to execute by
xargs
isn't working, as you see. Try it the other way around:The difference is that your version creates a command like
and sudo can't handle so many parameters.
Doing it the other way around executes sudo once, which in turn starts
xargs
which then generates a command likeand if
optipng
can handle many files as parameters, it should work.If that still doesn't work, you will have to use
-exec
instead like in Geraint's answer, but this should be your last resort.Yet another shot at this:
find . -name '*.png' | sudo xargs -n x -P y optipng -o2
Which will start one optipng for
x
files andy
such processes in parallel (might help you get things done faster if you have some cores to spare). Havingx
greater than 10 probably won't have great impact on performance.That will help keep the argument list short. So you could probably move
sudo
to where you had it, but that's just another command that would have to be run for every batch.