Shell script filtering through jpg files attributes

imagesjpegscriptingshell

I'm trying to find a way to filter through thousands of jpg files, and keep only the files with a certain attribute (such as the camera brand with which the picture was captured). How can I do so?

Best Answer

There are several tools that can extract EXIF data or even manipulate image files based on their EXIF data.

With exiftool, you can rename files based on exif properties. In particular, you can easily dispatch files into subdirectories named after a particular exif property. You can then review the results and delete the directories containing files that you aren't interested in to your leisure.

exiftool  '-Directory<${Model}/%d' -r .

Exiftool makes this easy, but for illustration, here's a shell snippet that sorts jpeg files into subdirectories based on an EXIF property using exif. The property value must not contain / characters. You can find out the number for the -t option by running exif -l.

for f in *.jpg; do
  v=$(exif -m -t 0x0110 -- "$f" 2>/dev/null)
  if [ -n "$v" ]; then
    mkdir -p -- "$v"
    mv -- "$f" "$v"
  fi
done

With Exiv2, replace the v=… line by v=$(exiv2 -g Exif.Image.Model -Pv -- "$f").

If your files are organized in a directory tree already, call find to traverse the directory tree recursively. Assume all your images are under a directory called unknown. The snippet below creates a directory for each image model and copies the files, mirroring the original directory hierarchy.

find unknown -name '*.jpg' -exec sh -c '
    v=$(exif -m -t 0x0110 -- "$f" 2>/dev/null)
    [ -n "$v" ] || exit
    d=${0#*/}; d=${d%/*}
    mkdir -p -- "$v/$d"
    mv "$0" "$v/$d"
' {} \;
Related Question