I am using imageOptim to optimize images on my server.

It took me quite some time to learn rudimentary bash scripting to able to optimize all images in all my first level directories. My script looks the following way and from functional point of view it does exactly what I want:

for dir in mydir/*/
    sudo jpegoptim --strip-all -t "$dir"*.jpg

The problem is with aestetic angle. When I run the script it outputs the following:

mydir/dir_1/img_1.jpg axb 24bit N JFIF  [OK] 2234 --> 1861 bytes (16.70%), optimized.
mydir/dir_1/img_16.jpg axb 24bit N JFIF  [OK] 2234 --> 1861 bytes (16.70%), optimized.
Average compression (16 files): 7.26% (8k)
mydir/dir_2/img_1.jpg axb 24bit N JFIF  [OK] 2234 --> 1861 bytes (16.70%), optimized.
mydir/dir_2/img_6.jpg axb 24bit N JFIF  [OK] 2234 --> 1861 bytes (16.70%), optimized.
Average compression (6 files): 7.26% (8k)

It outputs the line Average compression (6 files): 7.26% (8k) because I asked for summary with (-t) flag. But I do not want to get all information about each particular resource. When I try to suppress it with -t -q or -tq or -q -t (I tried them all because I am not sure it it matters) it showed no information at all.

In the very perfect case I just want to see one number - how much size have I saved. Because this is my first bash script (I struggled for an hour with that loop :-( ), my skills currently are not sufficient to solve my problem.

  • It's easy.But first tell me what do you mean by "how much size I saved". For example can you tell exactly what number from the mydir/dir_1/img_1.jpg axb 24bit N JFIF [OK] 2234 --> 1861 bytes (16.70%), optimized. output you want? – Registered User Mar 21 '14 at 8:07
  • The tool shows how many bytes was saved for every file (the file decreased from 2234 to 1861 bytes). Tools gives such info for every file in directory. With the help of -t I can get that the whole dir_1 saved 8k. So basically there is no point in calculating the size for every file. All I need is to add all the directory savings (8kb + ... for every dir) – Salvador Dali Mar 21 '14 at 8:11
  • You can get output such as 8k 9k 3k each on newline with a simple awk command.adding them up will need a little more complex programming. – Registered User Mar 21 '14 at 8:21
  • Do you want to see the details of the savings for each directory, or just the total savings? – Gilles 'SO- stop being evil' Mar 21 '14 at 11:11
  • I would like to see just one information. How much spaces was saved in total. BTW, I almost finished my way of calculating this. – Salvador Dali Mar 21 '14 at 11:23

You can try this oneliner using find and perl:

sudo find . -type d -exec  sh -c "./jpegoptim --strip-all -t {}/*.jpg" \; | perl -e '@a=<>; $a=join("", @a); @b = $a =~ /%\s+\((\d+)k\)/g; foreach my $n (@b) {$sum = $sum + $n}; print "Total saved ${sum}k\n"'

You need to copy jpegoptim in the directory where you start the find command of course.

A bash loop is not really needed, a find can filter directories with -d type.

The perl part will just parse for "% (the saved size per dir k)" and sum all the values before printing a single line with just the sum.

  • find . -type d only returns the directories.
  • -exec <command> \; will start the given command for each directory
  • sh -c "" is required as we need a shell to interpret the *.jpg wildcard.
  • the whole output is piped | to perl
  • perl first create an array with stdin (<>, the diamond operator), @a.
  • Then joined into a string, $a
  • @b = $a =~ /%\s+\((\d+)k\)/g will put in array @b all the matched strings included in the average compression summary lines using a regular expression
  • Finally foreach my $n (@b) {$sum = $sum + $n} sum all arrays values before printing the result
  • It would be nice if you could explain each command in short. – Registered User Mar 21 '14 at 8:56
  • actually my folders with images do not have enough permissions to modify them, therefore I run it with sudo. Without sudo I got errors. Thanks for your help. I will try it. – Salvador Dali Mar 21 '14 at 9:28
  • I modified my answer accordingly – Sylvain Pineau Mar 21 '14 at 9:30

After hours of improving my basic unix/bash skills I found what I think is an amazing way to do this. It is so simple that I am surprised that I wasted so much time. So here is the code:

du -s mydir/
for dir in mydir/*/
    sudo jpegoptim --strip-all -q "$dir"*.jpg
du -s mydir/

That's it the difference between the first and the second output will give me how much space I have saved in KB. du -s mydir/ will tell me the size of the folder before optimization, the same one in the end - after optimization.

If I would be better at bash, I would be able to save the first one in some variable, subtract the second. But even this is good for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.