15,000 unorganized photos

I have some 15,000 photos that are unorganized. In part, this is because of the rapid changes in both camera and computers used. Thankfully, they are backed up. So, a second step is organizing them is to group them by year and month. I don't think I need day, but that might change. Most of the photos have encoded within them the date and time they were taken. To organize them I just need this data and a means to associate them. The following Perl script does this by using the Image::MetaData::JPEG module, dated directories, and symbolic links.


find ~/Dropbox -type f \( -iname '*.jpeg' -o -iname '*.jpg' \) \
| perl organize.pl ./PICTURES 2>/dev/null >./PICTURES.sh

Once the PICTURES.sh script has been made it can be run using

bash -xe PICTURES.sh 2>&1 >PICTURES.log

The Perl script organize.pl is

#!/usr/bin/perl -w

use strict;
use Image::MetaData::JPEG;

my $root = shift @ARGV;
die "root is not a directory" unless defined $root && -d $root;

my $count = 10000;

my %mkdirs = ();

while ( my $file = <> ) {
  chomp $file;

  my $dir = "unusable";

  my $image = new Image::MetaData::JPEG($file);
  if ( defined $image ) {
    my $metadata = $image->get_Exif_data('IMAGE_DATA', 'TEXTUAL');
    if ( exists  $metadata->{DateTimeOriginal} && $metadata->{DateTimeOriginal}->[0] =~ /^(\d\d\d\d):(\d\d)/ ) {
      $dir = "$1/$2";            
    else {
      $dir = "undated";

  unless ( exists $mkdirs{$dir} ) {
    print "mkdir -p $root/$dir\n";
    $mkdirs{$dir} = 1;

  my $efile = $file; $efile =~ s/([^a-zA-Z0-9_\.\/])/\\$1/g;
  print "ln -s $efile $root/$dir/$count.jpg\n";

  $count += 1;

And why is this the second step? Because removing duplicates is the first.

Update: I did use this to organize my photographs held in DropBox. I replaced the symbolic link command with a move command. DropBox just moved the files and not, as I was worried about, re-upload the whole collection. Thank you DropBox engineering.