The majority of my photo files have the following naming convention / format IMG_20131204_120000.JPG, showing date and time the photo was taken (iPhone/Apple naming convention). However, not all my photos follow this naming convention. With the help of this forum I developed the following script to categorize my photos into date directories:

cd '/photos/' 
for x in *.JPG *.jpg *.TIF *.tif *.PNG *.png *.BMP *.bmp *.GIF *.gif *.IMG *.img *.JPEG *.jpeg *.TIFF *.tiff; do
  d=$(date -r "$x" +%Y%m%d)" - Family Photos"
  t=$(expr substr "$x" 1 4)
  if [ "$t" == "IMG_" ]; then
    d=$(expr substr "$x" 5 8)" - Family Photos"
  mkdir -p "$d" >/dev/null 2>&1
  mv -- "$x" "$d/" >/dev/null 2>&1

PS. I use the IF statement to take the date from the File name itself if the filename is in the format IMG_20131204_120000.JPG as this date most accurately reflects the date the photo was actually taken, but if the file doesn't follow this naming convention I take the operating system date of when the file was last modified/created.

It works fine for the most part except where there are files that start with "IMG_" but then don't conform to the naming convention IMG_20131204_120000.JPG, for example a file called IMG_001.JPG or IMG_Photo1. Is there a better way to structure the IF statement here so that it checks not only that the file starts with "IMG_" but also the next 8 characters are numbers / a date format?


You can change your if command to something like this:

if [[ "$t" =~ IMG_+[0-9]{8}[a-zA-Z]*$ ]]

The =~ is a regular expression comparison operator which is introduced in bash version 3 and above.

By using this if statement you can catch names like IMG_11111111alphabets.ext. You can play with it and customize it according to your needs. For more information have a look at this: Bash's regular expression

  • Unfortunately my system (Synology) doesn't support BASH only ASH. I assume no easy way to do this under ASH shell? – Wags Dec 7 '13 at 13:18
  • @Wags I guess you can instead use what is called Shell Patterns in a case clause or something like that to achieve the same results in ASH. Take a look here (Shell Patterns): linux.about.com/library/cmd/blcmdl1_ash.htm – coffeMug Dec 8 '13 at 9:24

I might go about this a little differently. ImageMagik can read the exif metadata from your image files. The format does not change.

identify -verbose example.jpg

returns (along with a lot of other information)


date:create: 2013-11-07T04:55:55-06:00
date:modify: 2013-11-07T04:55:55-06:00

You could grep the create date and then parse it so you really wouldn't need to deal with the conditional statements or parse a strange file name at all

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.