3

This is a follow-up question from my previous question asked here. I need to find and log the path to all jpeg images in sub directories with a resolution higher than a specific number (e.g. higher that 800 in width).

Well, there are millions of images, and I wonder why the find process below is so slow. So I need to optimize the bash script to make it faster:

find -type f -regex "^.*\.\(png\|jpg\|jpeg\)$" -exec identify -format "%d/%f, %w, %h\n" {} \; | awk -F ',' '$2 > 800 && $3 > 600'

But there is an interesting feature: I have 4 major directories (1 to 4), each exactly with 256 sub-directories. Each of these sub-directories have around 5000 sub-sub-directories, each having around 10 images. So it looks like major_dir/subdir/subsubdir/10.jpg. The interesting feature is that all images in these sub-sub-directories have the same resolution; so I don't really need to process all of these 10 images. If the resolution of one of them satisfies, then I would just need to log a single path (the sub-sub-directory path). With that, hopefully I will get 10x faster speed. And plus, all my images are .jpg if that also helps.

How can I do this in bash script? So an ideal output would look like this (path, width_of_images_there, height)

/path/to/sub_dir1, 1600, 1200
/path/to/sub_dir2, 1600, 1200
/path/to/sub_dir3, 3200, 2400
/path/to/sub_dir4, 1000, 800
2

How about that:

find /path/to/dir_with_major_dirs -path "*/*/*/*.jpg" -type f -exec bash -c '
  for i; do
    [[ "$p" = "${i%/*}" ]] || identify -format "%d, %w, %h\n" "$i"
    p="${i%/*}"
  done' _ {} + |
awk -F ',' '$2 > 800 && $3 > 600'

This test for every jpg file found whether its path matches the previous file’s path and only if not runs identify. The output is piped to awk as you already figured out, I just removed /%f from the identify command to get rid of the unnecessary file name.

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.