Renaming Screenshots - wsmoak/wiki GitHub Wiki

Really, Apple? This should have been simple. All I wanted to do is rename screenshots to get rid of the spaces.

When you use cmd + shift + 4 and draw a box on the page, Apple writes a file called, for example Screenshot 2025-06-09 at 8.30.10 AM.png. You can configure the prefix to be something else, but the rest is controlled by system settings.

If you have set it to use a 24-hour clock then the time will use a two-digit hour such as 08.32.02 instead of showing AM or PM.

I prefer to name my image files with the pattern 250609_12345.png.

Again, simple with some text manipulation. Let's get rid of the spaces:

SCREENSHOT=$(find . -maxdepth 1 -name "Screenshot*.png" | head -n1)
echo $SCREENSHOT
Screenshot 2025-06-09 at 8.30.10 AM.png

$ echo $SCREENSHOT | tr -d ' '
./Screenshot2025-06-09at8.30.10 AM.png

Wait, what? Why is there still a space before 'AM'?

It turns out that space before the AM (or PM) is not a normal space, it is a NARROW NO-BREAK SPACE (U+202F).

To make a long story short, with help from Claude, extracting the time from the filename turns into this:

TIME_PART=$(echo "$BASENAME" | cut -c26-33 | tr -d '.' | tr -d $'\xE2\x80\xAF')

Full Script

#!/bin/bash
SCREENSHOT_DIR="$HOME/Pictures"
cd "$SCREENSHOT_DIR"

# Make sure that screenshots are going into the Pictures directory
# $ defaults write com.apple.screencapture location ~/Pictures
# $ killall SystemUIServer

SCREENSHOT=$(find . -maxdepth 1 -name "Screenshot*.png" | head -n1)

if [ -n "$SCREENSHOT" ]; then

    BASENAME=$(basename "$SCREENSHOT")

    echo "Found screenshot: $BASENAME"

    # Extract date part (after prefix, 8 chars for YY-MM-DD)
    DATE_PART=$(echo "$BASENAME" | cut -c14-21 | tr -d '-')

    # Extract time part (after " at ", 8 chars for HH.MM.SS)
    # Remove both the dots and the Unicode NARROW NO-BREAK SPACE (U+202F)
    # that appears before the AM or PM in the screenshot filename.
    # since if the os is set to 12-hour format, most of the time
    # there is only one char for the hour and the weird space gets picked up.
    # The special space character is written in the tr command as \xE2\x80\xAF
    # Alternately, use 24-hour time and this is not a problem.

    TIME_PART=$(echo "$BASENAME" | cut -c26-33 | tr -d '.' | tr -d $'\xE2\x80\xAF')

    # Combine into new filename
    NEW_NAME="${DATE_PART}_${TIME_PART}.png"

    echo "Renaming to: $NEW_NAME"

    # Move the file
    # mv "$SCREENSHOT" "$NEW_NAME"
fi

To have the system watch the Pictures directory and rename any screenshot that appears -- edit with your own username:

$ cat ~/Library/LaunchAgents/net.wsmoak.screenshot.rename.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>net.wsmoak.screenshot.rename</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/Users/wsmoak/bin/screenshot_rename.sh</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/Users/wsmoak/Pictures</string>
    </array>
</dict>
</plist>

Installing / enabling / disabling it is still somewhat of a mystery. It mostly works though.

launchctl load ~/Library/LaunchAgents/net.wsmoak.screenshot.rename.plist  

Check that it's there

$ launchctl list | grep screenshot                    
-       0       net.wsmoak.screenshot.rename
⚠️ **GitHub.com Fallback** ⚠️