Skip to content

Instantly share code, notes, and snippets.

@feklee
Last active August 10, 2023 06:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save feklee/85b5f13e83c796472dda16e31e32b7f3 to your computer and use it in GitHub Desktop.
Save feklee/85b5f13e83c796472dda16e31e32b7f3 to your computer and use it in GitHub Desktop.
Sorts media files into directories by the date when they were created
#!/bin/bash
# Sorts media files into directories by the date when they were
# created. There is no time zone conversion: Many media files don't
# contain a time zone, or they default to UTC.
# Felix E. Klee <felix.klee@inka.de>
shopt -s nullglob
PICTURE_FORMATS="*.jpg *.JPG *.jpeg *.dng *.DNG *.arw *.ARW *.png *.PNG"
VIDEO_FORMATS="*.mov *.MOV *.mp4 *.MP4"
SOUND_FORMATS="*.wav *.WAV"
extract_screenshot_date_format_1() {
regex="Screenshot_([0-9]{4}-[0-9]{2}-[0-9]{2}).*"
if [[ $1 =~ $regex ]]
then
echo ${BASH_REMATCH[1]}
fi
}
extract_screenshot_date_format_2() {
regex="Screenshot_([0-9]{4})([0-9]{2})([0-9]{2})-.*"
if [[ $1 =~ $regex ]]
then
echo ${BASH_REMATCH[1]}-${BASH_REMATCH[2]}-${BASH_REMATCH[3]}
fi
}
extract_exif_date() {
exiv2 -g Exif.Image.DateTime -Pv "$1" | \
sed -E 's/^([0-9]{4}):([0-9]{2}):([0-9]{2}).*/\1-\2-\3/'
}
extract_picture_date() {
d=$(extract_exif_date "$1")
if [[ -z $d || $d == "-" ]]
then
d=$(extract_screenshot_date_format_1 "$1")
fi
if [[ -z $d || $d == "-" ]]
then
d=$(extract_screenshot_date_format_2 "$1")
fi
echo $d
}
extract_video_date() {
# Don't convert time zone, leave as is!
s=$(ffprobe -v quiet -print_format flat -show_format "$1" | grep creation_time | cut -d= -f2-)
echo ${s:1:10}
}
extract_sound_date() {
s=$(ffprobe -v quiet -print_format flat -show_format "$1" | grep format.tags.date | cut -d= -f2-)
echo ${s:1: -1} # removes quotes
}
extract_date() {
for a in $PICTURE_FORMATS
do
if [ "$1" == "$a" ]
then
extract_picture_date "$1"
fi
done
for a in $VIDEO_FORMATS
do
if [ "$1" == "$a" ]
then
extract_video_date "$1"
fi
done
for a in $SOUND_FORMATS
do
if [ "$1" == "$a" ]
then
extract_sound_date "$1"
fi
done
}
for a in $PICTURE_FORMATS $VIDEO_FORMATS $SOUND_FORMATS
do
d=$(extract_date "$a")
if [[ -z $d || $d == "-" ]]
then
continue
fi
mkdir -p "$d"
echo "Moving $a to $d/$a"
mv -i "$a" "$d/$a"
sidecar_filename="$a.xmp"
if [[ -f "$sidecar_filename" ]]
then
echo "Moving $sidecar_filename to $d/$sidecar_filename"
mv -i "$sidecar_filename" "$d/$sidecar_filename"
fi
b="${a%.*}"
sidecar_filename="$b.xmp"
if [[ -f "$sidecar_filename" ]]
then
echo "Moving $sidecar_filename to $d/$sidecar_filename"
mv -i "$sidecar_filename" "$d/$sidecar_filename"
fi
c="${a%.*}"
sidecar_filename="$c"M01.XML # Used by Sony for videos, for example
if [[ -f "$sidecar_filename" ]]
then
echo "Moving $sidecar_filename to $d/$sidecar_filename"
mv -i "$sidecar_filename" "$d/$sidecar_filename"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment