#!/usr/bin/env bash # This script takes all the jpg and mp4 files in a directory and # organises them into a folder structure based on the month and year # they were last modified (taken). # Sources and References # - Bash controlled paralellisation - http://unix.stackexchange.com/a/216475/64687 DRY_RUN=false while test $# -gt 0 do case "$1" in --help) echo organise-photos echo " by Starbeamrainbowlabs " echo "This script takes all the jpg and mp4 files in a directory and organises them into a folder structure based on the month and year they were last modified (taken)." echo echo "Options:" echo " --help" echo " Show this help message" echo " --dry-run" echo " Do a dry run - don't actually move any files." exit ;; --dry-run) echo Activating dry run mode. DRY_RUN=true esac shift done Months=(Zero January February March April May June July August September October November December); handle_file() { local filename=$1; echo -ne "Processing ${filename} - "; rawFilename=$(basename "${filename}"); extension=${filename##*.}; extension=${extension,,}; takenYear=$(date -r "${filename}" +%Y); takenMonth=$(date -r "${filename}" +%-m); takenMonthText=$(date -r "${filename}" +%B); # Extract the date taken from jpegs if [[ "${extension}" == "jpg" ]] || [[ "${extension}" == "jpeg" ]]; then takenDate=$(jhead "${filename}" | grep -i 'Date/Time' | cut -d' ' -f6-7); takenChars=$(echo ${takenDate} | wc -c); if [[ ${takenChars} -gt 1 ]]; then takenYear=$(echo ${takenDate} | cut -d ':' -f1); takenMonth=$(echo ${takenDate} | cut -d ':' -f2); takenMonthUnpadded=$(echo ${takenMonth//0}); takenMonthText=${Months[$takenMonthUnpadded]}; fi fi #takenMonth=$(printf "%02d" "${takenMonth}"); newFolder="${takenYear}/${takenMonth}-${takenMonthText}/"; newFilename="${newFolder}/${filename}"; echo -ne "filing in ${newFolder} - "; if [ "$DRY_RUN" = true ] ; then echo dry run continue fi mkdir -p "${newFolder}"; mv "${filename}" "${newFilename}"; echo Done\!; } # Set the number of paralell jobs to the number of cpus N=$(grep -c ^processor /proc/cpuinfo); find . -maxdepth 1 \( -iname "*.jpg" -o -iname "*.mp4" -o -iname "*.avi" -o -iname "*.png" \) -print0 | while read -r -d '' filename do ((i=i%N)); ((i++==0)) && wait; handle_file "${filename}" done echo "*** Complete! ***" exit 0