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 we evolved the script as follows:

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"
  if [[ "$x" =~ ^[iI][mM][gG][_-][1-2][09][0-9][0-9][0-1][0-9][0-3][0-9][_-][0-2][0-9][0-6][0-9][0-6][0-9][.][a-zA-Z]*$ ]]; then
    d=$(expr substr "$x" 5 8)" - Family Photos"
  mkdir -p "$d" >/dev/null 2>&1
  mv -- "$x" "$d/" >/dev/null 2>&1
rmdir ' - Family Photos' >/dev/null 2>&1

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.

I plan to run this script every night to categorize the photos uploaded during the previous 24 hours. My problem is I now find out that my Synology system only supports ASH not BASH shell and therefore the regular expression =~ in the if statement doesn't work. I can use IPKG to install a BASH package. Is there an easy way to have just this script use BASH while the rest of the system is untouched and uses ASH? Or alternatively is there a way to do the same thing in the if statement using the ASH shell?

  • Photo image files often contain EXIF data with the exact date/time, that don't change if the filename changes. – Zelda Dec 7 '13 at 15:58

Ash doesn't have regular expressions, but it has shell wildcard matching. You need to use case, wildcard matching isn't available via test a.k.a. [ … ].

There is no way to express the regex [a-zA-Z]* using wildcards, but you can perform the same test in two steps, one for the first part and one for the second part.

case "$x" in
    case "${x#*.}" in
      *[!a-zA-z]*) :;;
      *) d=${x#*[-_]}; d="${d%%[-_]*} - Family Photos";;

The prefix and suffix stripping constructs are portable to all POSIX shells, you don't need to use expr.

  • Finally got around to implementing this after researching exactly how the script works. I learned a lot thank you. Works perfect. Genious. – Wags Jan 18 '14 at 16:24

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.