I've been playing with Ubuntu 8.04 (Hardy) for the past couple of days. It's an amazing distribution, way better than anything I've seen before. As a desktop distribution everything seems to run out of box. I remember how painful (yet fun) was a Linux install eight years ago, when I was spending my nights recompiling the kernel, in order to get the trivial things working (cdrom, modem, sound, video card, etc.). I've managed to set up Hardy in about an hour or so - and that includes updating the ATI drivers as well.
One of the things that I love about the Canon photo management software that came with my camera (Canon 350D) is the ability to keep the photos organised in folders, by date. Sounds very simple, but it's really one of the things that I missed most while running Linux. I've tried several photo management packages, but they either lacked this feature, or they didn't allow the user to customize the folder names. And having both a "2008_05_19" and "2008-05-20" is not an option for me. No way!
But again, one of the nice things about Linux, and Unix in general, is that you can always do the things your way. It might not be very appealing for non-technical people, but it should be quite simple for someone with a basic programming experience - and Google around.
I'll provide a simple shell script that takes a source folder, a file extension and moves all the matching files into a nice, date organised, folder structure.
The main problem is that the date when the photo was taken might not be the same as the file date. Actually, gThumb for example, saves the file with the date when the images were downloaded from the camera. This might not be a problem if you're downloading today's photos, but if you're downloading the photos from a two week trip - there's not much point in having them stored in a single folder, with the current date.
Hence, we will have to obtain the date / time when the picture was taken. Most cameras - including Canon 350D - save this information inside the EXIF tag "CreateDate". But grabbing the EXIF information from a file might not be very straightforward - and this is where exiftool comes into play.
Exiftool is a nice console application that can get/set most (if not all) EXIF tags. Even more, it's very script-friendly as you'll see in the next steps.
Having the photo creation date, the process is quite simple. We create a directory having the creation date as its name and place the photo there. Here is the complete shell script:
#!/bin/bash # The directory where the photos are SOURCE_DIR=Photos # The destination directory DEST_DIR=/media/drive_d/Photos # The date pattern for the destination dir (see strftime) DEST_DIR_PATTERN="%Y_%m_%d" # Move all files having this extension EXTENSION=cr2 for f in `find "$SOURCE_DIR" -iname "*.$EXTENSION" -type f`; do # Obtain the creation date from the EXIF tag f_date=`exiftool $f -CreateDate -d $DEST_DIR_PATTERN | cut -d ':' -f 2 | sed -e 's/^[ \t]*//;s/[ \t]*$//'`; # Construct and create the destination directory f_dest_dir=$DEST_DIR/$f_date if [ ! -d $f_dest_dir ]; then echo "Creating directory $f_dest_dir" mkdir $f_dest_dir fi mv "$f" "$f_dest_dir" echo "Moved $f to $f_dest_dir" done
Before running this script, please change the variables defined in the header as required. The script should work for any image format supported by exiftool. Until now, I've only tested it with CR2 files (Canon RAW, as created by Canon 350D) - please let me know if it's not working for you.
Note: If you're using Ubuntu, you can install exiftool with the following command:
sudo apt-get install libimage-exiftool-perl
Other distributions might include a similar package in their repository. You can always check the official exiftool page for the latest version.
Interesting script, but using exiftool you can do all this in one command:
exiftool -d /media/drive_d/Photos/%Y_%d_%d "-directory<createdate" FILE
where FILE is one or more directory or file names. This will create directories that didn't exist too.
Also, you can write the "FileName" tag with a full path specification + file name if you want to rename the files at the same time that you move them.
exiftool -d /media/drive_d/Photos/%Y_%d_%d "-directory
I was looking for something just like this and it's been super-useful. Instead of organizing photos already on disk, I use it to transfer the pictures off the camera. Thanks!
One small improvement:
My Ubuntu (8.0.4) mounts my camera in /home/phamlen/.gvfs as something called "gphoto2 on usb%yadayada". The spaces in the file names makes the original find command break (because each word gets parsed instead of each filename. It's pretty easy to fix though; just change the for loop to a while loop and read the lines. Also, add quotes around $f in the move script. It looks something like:
find "$SOURCE_DIR" -iname "*.$EXTENSION" -type f | while read f
do
# Obtain the creation date from the EXIF tag
f_date=`exiftool "$f" -CreateDate -d $DEST_DIR_PATTERN | cut -d ':' -f 2 | sed -e 's/^[ \t]*//;s/[ \t]*$//'`;
# Construct and create the destination directory
f_dest_dir=$DEST_DIR/$f_date
if [ ! -d $f_dest_dir ]; then
echo "Creating directory $f_dest_dir"
mkdir $f_dest_dir
fi
mv "$f" "$f_dest_dir"
echo "Moved $f to $f_dest_dir"
done
Thanks again!
Thank you both from the bottom of my heart for this script. It's a life savior for me as I need my pictures organized in folders with the same name as the date the picture was taken. I use to take pictures for weeks and months and just keep them on my 4GB camera SD card (the pictures are on the camera SD card in the DCIM/255CANON folder) before downloading them on my computer. Therefore, your script was most useful. I had to tweak the Peter Halmen's code a little, as my camera is mounted on variable .dvfs subfolders, depending on USB allocation by Ubuntu. In other words, each time I connect my Canon PowerShot S5 to the computer, Ubuntu mounts it on a .gvfs subfolder like "gphoto2 mount on usb%A100, 113", "gphoto2 mount on usb%A300, 116", etc. Since I cannot be sure what would be the name of that subfolder, I take it as a variable as such:
#!/bin/bash
# The directory where the photos are (inside my camera SD card)
SOURCE_DIR=".gvfs"$(ls .gvfs)"/DCIM/255CANON"
# The destination directory
DEST_DIR=Pictures
# The date pattern for the destination dir (see strftime)
DEST_DIR_PATTERN="%Y_%m_%d"
# Move all files having this extension
EXTENSION=JPG
find "$SOURCE_DIR" -iname "*.$EXTENSION" -type f | while read f
do
# Obtain the creation date from the EXIF tag
f_date=`exiftool "$f" -CreateDate -d $DEST_DIR_PATTERN | cut -d ':' -f 2 | sed -e 's/^[ \t]*//;s/[ \t]*$//'`;
# Construct and create the destination directory
f_dest_dir=$DEST_DIR/$f_date
if [ ! -d $f_dest_dir ]; then
echo "Creating directory $f_dest_dir"
mkdir $f_dest_dir
fi
mv "$f" "$f_dest_dir"
echo "Moved $f to $f_dest_dir"
done
Thank you SO much for this.
Razvan
I got my wife to change to Ubuntu 9.10 about 3 weeks ago. The Canon utility would do all this for you but does not work in Ubuntu. I found a number of programs that "are supposed to do this" but non actually work. Here is my version that works but with a few changes. I added a lot of comments so it should be easy to read and modify to your liking. It will automatically launch this script whenever a phone is plugged in on her box now. I had to keep it as simple as possible.
#!/bin/bash
# sudo apt-get install libimage-exiftool-perl
# sudo apt-get install libnotify-bin
# The directory where the photos are (inside my camera SD card)
# This path works for both my Canon PowerShot S5IS and iPhone
SOURCE_DIR=".gvfs/"$(ls .gvfs)"/DCIM"
# A temporary location to store the files
# This way we still have the originals just in case
TEMP_DIR=TEMP
# The destination directory
DEST_DIR=Pictures
# Lets copy the files first
cp -R $SOURCE_DIR $TEMP_DIR
# I move the pictures first
exiftool -r -d $DEST_DIR/%Y/%m/%d/image_%Y_%m_%d%%-c.%%e "-filename
I'm glad it was useful and thanks for the suggestions!
Hi there...
Great little script, I needed it very much too. Modified it a bit, so it puts the pictures in /year/month/year_month_date..
Cheers!