-
-
Save paulgalow/70bff79dcf1f4a0ec74ccff6e50e1bc9 to your computer and use it in GitHub Desktop.
#!/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 |
Hi, I am using your code, but there seems to be an error. The timestamp after the photo is renamed does not correlate with the actual time stamp on the photo. For instance, a photo was renamed to 2020-07-03 18 01 07.jpg, but the actual timestamp is at 11:01 am, not 6:01 pm. Everything else is correct except for the time. Also, how can I get rid of the dashes on the date? All the renamed dates are off by 7 hours too much.
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//[:|-]/}
.
how do I change from UTC? The photos are collected PST
Also thank you for getting rid of the dashes!
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
Hi!
Sorry for being late to the party, but your script a the Link above helped me a lot! Thanks!
Solved the UTC Problem by using "date -f" and geplaced the whitespace between date and time:
mdls_date=$(mdls -rnkMDItemContentCreationDate "$file" )
creation_date=$(date -f"%F %T %z" -j "$mdls_date" "+%F %T %z" | cut -d ' ' -f -2 )
timestamp=${creation_date//:/}
timestamp=${timestamp// /_}
Hope it helps.
(Tested as zsh Script inside of Apple Automator)
Thanks for pointing me to this, @alisey. I have updated the gist after your suggestion. And sorry for my late reply. I somehow managed to completely miss your comment.