-
-
Save jvhaarst/2343281 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# Reads EXIF creation date from all .JPG files in the | |
# current directory and moves them carefully under | |
# | |
# $BASEDIR/YYYY/YYYY-MM/YYYY-MM-DD/ | |
# | |
# ...where 'carefully' means that it does not overwrite | |
# differing files if they already exist and will not delete | |
# the original file if copying fails for some reason. | |
# | |
# It DOES overwrite identical files in the destination directory | |
# with the ones in current, however. | |
# | |
# This script was originally written and put into | |
# Public Domain by Jarno Elonen <[email protected]> in June 2003. | |
# Feel free to do whatever you like with it. | |
# Defaults | |
TOOLS=(exiftool jq) # Also change settings below if changing this, the output should be in the format YYYY:MM:DD | |
DEFAULTDIR='/Users/jvhaarst/Pictures/van camera/van camera' | |
MAXDEPTH=-maxdepth 1 | |
#MAXDEPTH='' | |
# activate debugging from here | |
#set -o xtrace | |
#set -o verbose | |
# Improve error handling | |
set -o errexit | |
set -o pipefail | |
# Check whether needed programs are installed | |
for TOOL in ${TOOLS[*]} | |
do | |
hash $TOOL 2>/dev/null || { echo >&2 "I require $TOOL but it's not installed. Aborting."; exit 1; } | |
done | |
# Enable handling of filenames with spaces: | |
SAVEIFS=$IFS | |
IFS=$(echo -en "\n\b") | |
# Use BASEDIR from commandline, or default if none given | |
BASEDIR=${1:-$DEFAULTDIR} | |
for FILE in $(find $(pwd -P) $MAXDEPTH -not -wholename "*._*" -iname "*.JPG" -or -iname "*.JPEG" -or -iname "*.CRW" -or -iname "*.THM" -or -iname "*.RW2" -or -iname '*.ARW' -or -iname "*AVI" -or -iname "*MOV" -or -iname "*MP4" -or -iname "*MTS" -or -iname "*PNG") | |
do | |
INPUT=${FILE} | |
DATE=$(exiftool -quiet -tab -dateformat "%Y:%m:%d" -json -DateTimeOriginal "${INPUT}" | jq --raw-output '.[].DateTimeOriginal') | |
if [ "$DATE" == "null" ] # If exif extraction with DateTimeOriginal failed | |
then | |
DATE=$(exiftool -quiet -tab -dateformat "%Y:%m:%d" -json -MediaCreateDate "${INPUT}" | jq --raw-output '.[].MediaCreateDate') | |
fi | |
if [ -z "$DATE" ] || [ "$DATE" == "null" ] # If exif extraction failed | |
then | |
DATE=$(stat -f "%Sm" -t %F "${INPUT}" | awk '{print $1}'| sed 's/-/:/g') | |
fi | |
if [ ! -z "$DATE" ]; # Doublecheck | |
then | |
YEAR=$(echo $DATE | sed -E "s/([0-9]*):([0-9]*):([0-9]*)/\\1/") | |
MONTH=$(echo $DATE | sed -E "s/([0-9]*):([0-9]*):([0-9]*)/\\2/") | |
DAY=$(echo $DATE | sed -E "s/([0-9]*):([0-9]*):([0-9]*)/\\3/") | |
if [ "$YEAR" -gt 0 ] & [ "$MONTH" -gt 0 ] & [ "$DAY" -gt 0 ] | |
then | |
OUTPUT_DIRECTORY=${BASEDIR}/${YEAR}_${MONTH}_${DAY} | |
mkdir -pv ${OUTPUT_DIRECTORY} | |
OUTPUT=${OUTPUT_DIRECTORY}/$(basename ${INPUT}) | |
if [ -e "$OUTPUT" ] && ! cmp -s "$INPUT" "$OUTPUT" | |
then | |
echo "WARNING: '$OUTPUT' exists already and is different from '$INPUT'." | |
else | |
echo "Moving '$INPUT' to $OUTPUT" | |
rsync -ah --progress "$INPUT" "$OUTPUT" | |
if ! cmp -s "$INPUT" "$OUTPUT" | |
then | |
echo "WARNING: copying failed somehow, will not delete original '$INPUT'" | |
else | |
rm -f "$INPUT" | |
fi | |
fi | |
else | |
echo "WARNING: '$INPUT' doesn't contain date." | |
fi | |
else | |
echo "WARNING: '$INPUT' doesn't contain date." | |
fi | |
done | |
# restore $IFS | |
IFS=$SAVEIFS |
Is 69 line correct or should be:
mkdir -pv ${OUTPUT_DIRECTORY} ?
Yeah, fixed now.
If $INPUT-Path equals $OUTPUT-Path you're just deleting the files.
Meaning if you run this script twice you delete all files which are already sorted.
Thanks for this script! I needed to modify lines 48 and 51 adding .val to make it work. Not sure why, probably my exiftool version (brew in osx el capitan)
DATE=$(exiftool -quiet -tab -dateformat "%Y:%m:%d" -json -DateTimeOriginal "${INPUT}" | jq --raw-output '.[].DateTimeOriginal.val')
Thanks for this 👍
Thanks for script ! How to also rename files based on some EXIF parameters like Nikon ShutterCount, Canon filenumber, etc. Thanks a lot
Thank you so much for such an amazing script, exactly what I've been looking for for so long.
Besides of fixing the jq
execution, I've also improved it a bit to handle the local timezone in dates from video files that are always in UTC and added CLI arguments: https://github.com/freefd/utils/blob/master/media_files_sort.sh.
The short documentation can be found at https://github.com/freefd/utils#media_files_sortsh
Nice, thank you. This script uses
exiftool
as dependency, sobrew install exiftool
for mac people.