Organise image files into year/month folders

I use MS OneDrive to sync photos taken on my Android phone to my Mac (they are synced to ~/OneDrive/Photos/Camera Roll). I would like to move the synced files into folders organised by Year and Month (Year/Month) that the photo was taken (or simply the file creation date).

Ideally this process would run whenever new photos are added to the Camera Roll folder.

I took a look at Automator Folder Actions, but it seems limited to only doing the exact same thing to everything that gets added to the folder (e.g. move all new items into a specific folder).

I found a PowerShell script that does exactly this in Windows, but haven't found any corresponding scripts or free apps that do this in macos.

Any suggestions?


Solution 1:

You could use the folder actions to run a bash script like this:

#!/bin/bash

DIR="/Users/USERNAME/OneDrive/Photos/Camera Roll"
target=$DIR
cd "$DIR" || exit

for file in *; do
    # Top year folder name
    year=$(stat -c "%y" "$file" | awk '{print substr($0,0,4)}')
    # Secondary folder name
    subfolderName=$(stat -c "%y" "$file" | awk '{print substr($0,6,2)}')

    if [ ! -d "$target/$year" ]; then
        mkdir "$target/$year"
        echo "starting new year: $year"
    fi
    if [ ! -d "$target/$year/$subfolderName" ]; then
        mkdir "$target/$year/$subfolderName"
        echo "starting new day & month folder: $subfolderName"
    fi
    echo "moving file $file"
    mv "$file" "$target/$year/$subfolderName"

done

You can also modify the directory names to include the day or the year and the month by changing the selected substring in the substr command.

Solution 2:

I found Organize - an open source and free of charge command line tool designed to do exactly this sort of thing.

The following config does the trick:

rules:
  # Move photos into Year/Month folders in My Photos
  - folders: ~/OneDrive/Pictures/Camera Roll
    filters:
    - extension: jpg
    - created
    actions:
     - move: ~/Pictures/My Photos/{created.year}/{created.month:02}/

I then created an Automator Folder Action that will Run a Shell Script anytime a file is added to the OneDrive Camera Roll:

/usr/local/bin/organize run --config-file=~/OneDrivePhotoSync.yaml