Skip to content

Instantly share code, notes, and snippets.

@elisboa
Last active January 7, 2023 22:45
Show Gist options
  • Save elisboa/eb91783588021e1cb76cc7ad519c66f9 to your computer and use it in GitHub Desktop.
Save elisboa/eb91783588021e1cb76cc7ad519c66f9 to your computer and use it in GitHub Desktop.
Photo and Video file sorter based on exiftool
#!/usr/bin/env bash
# ---
#!/bin/bash -x
echo -e "### WELCOME TO $(basename $0)\n"
if [[ -z ${DEST_DIR} ]]
then
TIMESTAMP=$(date +%s)
DEST_DIR=${TIMESTAMP}
fi
echo -e "Destination dir set as ${DEST_DIR}"
if [[ -n "${1}" ]]
then
echo -n "Analyzing ${1}... "
if [[ -e "${1}" ]]
then
echo OK
else
echo -e "FAIL!"
exit 1
fi
else
echo -e "Argument not set. Usage: ${0} file_name.jpg"
echo -e "\a"
exit 1
fi
echo -ne "Checking dependencies: "
for DEP in awk cut exiftool grep head mkdir rsync
do
echo -ne "$DEP "
if command -v $DEP > /dev/null 2>&1
then
echo -ne "OK\t "
else
echo "Failed to find $DEP command. Exitting now"
echo -e "\a"
exit 1
fi
done
echo -e \\n
EXIF_DATA="$(LANG=C exiftool "${1}")"
if [[ -n "${EXIF_DATA}" ]]
then
#echo -e "DEBUG: EXIF_DATA content is\n${EXIF_DATA}\n"
echo -e "Parsing information on file ${1}... "
FILE_NAME=$(echo "$EXIF_DATA" | grep '^File Name' | cut -d\: -f2- | cut -d\ -f2-)
FILE_EXTENSION=$(echo "$EXIF_DATA" | grep '^File Type Extension' | awk {'print $5'} )
if [[ -z $MAKER_NAME ]]
then
MAKER_NAME=$(echo "$EXIF_DATA" | grep '^Make' | awk {'print $3'} | xargs)
fi
if [[ ${FILE_EXTENSION} == "mov" ]]
then
DEVICE_NAME=$(echo "$EXIF_DATA" | grep '^Model' | awk {'print $3" "$4" "$5" "$6 " "$7" "$8" "$9" "'} | sed -e 's/[[:space:]]*$//' | xargs)
fi
if [[ $FILE_EXTENSION == "cr2" ]]
then
DEVICE_NAME=$(echo "$EXIF_DATA" | grep '^Camera Model Name' | awk {'print $5" "$6" "$7" "$8 " "$9" "$10" "$11" "$12" "'} | sed -e 's/[[:space:]]*$//' | xargs)
fi
### Device name fallback
if [[ -z $DEVICE_NAME ]]
then
DEVICE_NAME=$(echo "$EXIF_DATA" | grep '^Camera Model Name' | awk {'print $5" "$6" "$7" "$8 " "$9" "$10" "$11" "$12" "'} | sed -e 's/[[:space:]]*$//' )
fi
FILE_YEAR=$(echo "$EXIF_DATA" | grep '^Create Date' | head -n1 | awk {'print $4'} | cut -d\: -f1 )
FILE_MONTH=$(echo "$EXIF_DATA" | grep '^Create Date' | head -n1 | awk {'print $4'} | cut -d\: -f2 )
FILE_DAY=$(echo "$EXIF_DATA" | grep '^Create Date' | head -n1 | awk {'print $4'} | cut -d\: -f3 )
FILE_HOUR=$(echo "$EXIF_DATA" | grep '^Create Date' | head -n1 | awk {'print $5'} | cut -d\: -f1 )
FILE_MINUTE=$(echo "$EXIF_DATA" | grep '^Create Date' | head -n1 | awk {'print $5'} | cut -d\: -f2 )
FILE_SECOND=$(echo "$EXIF_DATA" | grep '^Create Date' | head -n1 | awk {'print $5'} | cut -d\: -f3 )
for INFORMATION in FILE_NAME FILE_EXTENSION MAKER_NAME DEVICE_NAME FILE_YEAR FILE_MONTH FILE_DAY FILE_HOUR FILE_MINUTE FILE_SECOND
do
echo -ne "${INFORMATION}: "
if [[ -z $(eval "echo \${$INFORMATION}") ]]
then
echo "FAILED. Variable \$${INFORMATION} is empty"
echo -e "\a"
exit 1
else
echo -ne $(eval "echo \${$INFORMATION}") \\n
fi
done
else
echo -e "No EXIF data found on file ${1}"
echo -e "\a"
exit 1
fi
echo
export FILE_NAME_FULL="${DEVICE_NAME// /_}-${FILE_YEAR}-${FILE_MONTH}-${FILE_DAY}-${FILE_HOUR}-${FILE_MINUTE}-${FILE_SECOND}.${FILE_EXTENSION}"
export FILE_NAME_SHORT="${FILE_HOUR}-${FILE_MINUTE}-${FILE_SECOND}.${FILE_EXTENSION}"
export FILE_NAME_ORIGINAL="${FILE_NAME}"
export FINAL_DEST_DIR="${DEST_DIR}/${MAKER_NAME}/${DEVICE_NAME}/${FILE_YEAR}/${FILE_MONTH}/${FILE_DAY}"
echo -n "Creating final destination dir ${FINAL_DEST_DIR}: "
if mkdir -p "${FINAL_DEST_DIR}"
then
echo -e "OK"
else
echo -e "FAILED. Exitting now"
echo -e "\a"
exit 1
fi
echo -n "Copying file ${1}: "
#if tar cp - "${1}" | tar xfp - -C "${DEST_DIR}"
if rsync -aqu -- "${1}" "${FINAL_DEST_DIR}" > /dev/null 2>&1
then
echo -ne "OK"
echo -ne " | Now renaming to ${FILE_NAME_FULL}: "
if mv -- "${FINAL_DEST_DIR}/${FILE_NAME}" "${FINAL_DEST_DIR}/${FILE_NAME_FULL}"
then
echo "OK"
else
echo "Full file renaming failed!"
if mv -- "${FINAL_DEST_DIR}/${FILE_NAME}" "${FINAL_DEST_DIR}/${FILE_NAME_SHORT}"
then
echo "File successfully renamed to ${FILE_NAME_SHORT}"
else
echo "Short file renaming failed. Keeping name as ${FILE_NAME})"
fi
fi
else
echo "File copy failed! Exitting now"
echo -e \\a
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment