Use a Script in Automator to classify files in a directory structure YYYY-MM-DD, getting it from their filenames

114 Views Asked by At

Having thousands of pictures and videos without meta-data date, but with the date structure at their name (ex: YYYYMMDD_HHMMSS.jpg), want to classify them in folders with their date, YYYY-MM-DD.

The idea is to use an action folder in Automator, so when I add pictures there, they classify automatically.

I tried with this code inside Automator, but it doesn't do anything even if doesn't give errors:

dest_dir=/Users/..........
# pattern to grab 4 digits of year 2 digits of month and 2 of the day
file_pattern="_([[:digit:]]{4})([[:digit:]]{2})([[:digit:]]{2})"
for file in test_file_*; do
  [[ ! -f $file ]] && continue  # look at regular files only
  if [[ $file =~ $file_pattern ]]; then
    year="${BASH_REMATCH[1]}"
    month="${BASH_REMATCH[2]}"
    day="${BASH_REMATCH[3]}"
    destination_dir="$dest_dir/$year-$month-$day"
    [[ ! -d $destination_dir ]] && mkdir -p "$destination_dir"
    echo "Moving $file to $destination_dir"
    mv "$file" "$destination_dir"
  fi
done

The code on Automator Example of the structure

1

There are 1 best solutions below

23
amphetamachine On

You almost had it. You were checking the part AFTER the _ in the filename. My updated example has the right fields checked:

Update 0: Applied fixes to script from feedback.

Update 1: The script was tested as working under Bash 3.2.57. No need for Homebrew.

dest_dir=/Users/myuser/photo-archive
# Note: Change `*.jpg` to `*.{jpg,mp4}` to also categorize videos
for file in /path/to/photos/*.jpg; do
  [[ -f $file ]] || continue  # look at regular files only
  filebase=$(basename -- "$file")
  if [[ $filebase =~ ^([[:digit:]]{4})([[:digit:]]{2})([[:digit:]]{2}) ]]; then
    year=${BASH_REMATCH[1]}
    month=${BASH_REMATCH[2]}
    day=${BASH_REMATCH[3]}
    destination_dir=$dest_dir/$year-$month-$day
    mkdir -p "$destination_dir"
    echo "Moving $file to $destination_dir"
    mv "$file" "$destination_dir"
  fi
done

Also, mkdir -p won't fail or warn if the directory already exists. Part of what's nice about it.

Also also, in the form var=$other_var double-quotes are not necessary unless the line contains a literal space, i.e. var="$foo $bar".

OSX runs Bash from 17 years ago

AFAIK Mac OSX still only ships with Bash 3.2 which came out 2006-10-11 (OSX users should use Homebrew to install Bash 5).

I'm not entirely certain this script not working is caused directly by this (Edit: it's not, I tested it), but it's something you're going to have to get used to if you continue to use OSX and write Bash scripts that work in OSX.

To work around the fact that OSX still hasn't updated the Bash version they give you in 17 goddamn years and counting, to write the script so that it should call the newer version of Bash installed from Homebrew, use this as your bangline:

#!/usr/bin/env bash