Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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 "$file" | awk '/^kMDItemContentCreationDate / { print $3 " " $4 }')
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
@eshill

This comment has been minimized.

Copy link

eshill commented Oct 21, 2019

Hi! Thanks for the script!
I tried to run it, but I see such a mistake:

When executing the "Run shell script" action, an error occurred: "zsh:1: no such file or directory: !/bin/bash 
cp: /2019-06-14 15-54-48.mov: Read-only file system 
presentResults:3: no matches found: /*.* 

You don't know how to fix it?

@paulgalow

This comment has been minimized.

Copy link
Owner Author

paulgalow commented Oct 21, 2019

It looks like you are running this with zsh as the interpreter. Perhaps there is an option to change that to bash? Since macOS Catalina the default shell has been switched from bash to zsh. That might be the issue here. Can you confirm you are running Catalina?

@eshill

This comment has been minimized.

Copy link

eshill commented Oct 21, 2019

Can you confirm you are running Catalina?

Yes!

@alisey

This comment has been minimized.

Copy link

alisey commented Oct 28, 2019

mdls has an option for printing only a specific attribute's value: mdls -name kMDItemContentCreationDate -raw <filename>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.