Skip to content

Instantly share code, notes, and snippets.

@paulgalow
Last active April 23, 2024 16:15
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save paulgalow/70bff79dcf1f4a0ec74ccff6e50e1bc9 to your computer and use it in GitHub Desktop.
Save paulgalow/70bff79dcf1f4a0ec74ccff6e50e1bc9 to your computer and use it in GitHub Desktop.
macOS Automator script to rename photos/videos based on creation date. Blog post: https://paulgalow.com/macos-quick-action-rename-photos-videos-timestamp
#!/bin/bash
# macOS Automator script to rename photos/videos based on creation date
# Blog post: https://paulgalow.com/macos-quick-action-rename-photos-videos-timestamp
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
# Create subfolder to store renamed files
createDestination() {
readonly destination="$(dirname "$file")/sorted"
mkdir -p "$destination"
}
# Check for file MIME type
hasMIMEType() {
file -I "$file" | grep -q "$1"
}
# Send notification to user
sendNotification() {
osascript <<-EndOfMessage
display notification \
"$1" \
with title "Rename (Timestamp)"
EndOfMessage
}
# Determine file extension
setFileExtension() {
if hasMIMEType "image/jpeg"
then
extension="jpg"
elif hasMIMEType "video/quicktime"
then
extension="mov"
else
return 1
fi
}
# Retrieve EXIF timestamp from media file
getTimeStamp() {
local -r timestampRaw=$(mdls -name kMDItemContentCreationDate -raw "$file" | cut -d ' ' -f -2)
timestamp=${timestampRaw//:/-}
}
# Rename file, handle timestamp collisions
renameFile() {
# Exit function if file type is not supported
setFileExtension || return 0
getTimeStamp || return 0
createDestination || return 1
# Check if to be renamed file already exists
if [[ -f "$destination/$timestamp.$extension" ]]
then
# If file exists append random string to file
local -r randomString=$(md5 -q "$file")
cp "$file" "$destination/$timestamp-$randomString.$extension"
else
cp "$file" "$destination/$timestamp.$extension"
fi
}
# Send notification to user after the process has finished
presentResults() {
# Count files in destination folder
local counter=0
for file in "$destination"/*.*
do
(( counter ++ ))
done
# Check if renaming was successful
if [ $counter != 0 ] && [ -n "$destination" ]
then
sendNotification "$counter photos/videos have been renamed. Opening destination folder…"
open "$destination"
else
sendNotification "Could not renamd any photos/videos."
fi
}
# Main loop to collect input files from Automator
processFiles() {
while read -r file; do
renameFile
done
}
sendNotification "Processing photos/videos.\\nThis can take a while…"
processFiles
presentResults
exit 0
@paulgalow
Copy link
Author

Hi @Minagamb, the resulting timestamps are UTC based so perhaps that explains why your timestamps are 7 hours off. Regarding the dashes on the date, try replacing timestamp=${timestampRaw//:/-} with timestamp=${timestampRaw//[:|-]/}.

@Minagamb
Copy link

Minagamb commented Oct 2, 2020

how do I change from UTC? The photos are collected PST

@Minagamb
Copy link

Minagamb commented Oct 2, 2020

Also thank you for getting rid of the dashes!

@Minagamb
Copy link

Minagamb commented Oct 2, 2020

how can I convert from UTC to my local time zone? or can I just subtract the 7 hours into the script so that each file has 7 hours subtracted from it? Sorry for bombarding you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment