115 lines
2.4 KiB
Bash
115 lines
2.4 KiB
Bash
#!/bin/bash
|
|||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Script Name: rename-images-by-date.sh
|
||
|
|
#
|
||
|
|
# Description:
|
||
|
|
# Renames image files using their original capture timestamp.
|
||
|
|
#
|
||
|
|
# The script:
|
||
|
|
# 1. Scans the target directory for image files.
|
||
|
|
# 2. Reads the EXIF DateTimeOriginal tag using exiftool.
|
||
|
|
# 3. Falls back to the file modification timestamp if EXIF data
|
||
|
|
# is unavailable.
|
||
|
|
# 4. Renames files to the format:
|
||
|
|
#
|
||
|
|
# IMG_YYYYMMDD_HHMMSS.ext
|
||
|
|
#
|
||
|
|
# 5. Automatically resolves filename collisions by appending a
|
||
|
|
# numeric suffix.
|
||
|
|
#
|
||
|
|
# Requirements:
|
||
|
|
# - Bash
|
||
|
|
# - exiftool
|
||
|
|
#
|
||
|
|
# Usage:
|
||
|
|
#
|
||
|
|
# Process current directory:
|
||
|
|
# ./rename-images-by-date.sh
|
||
|
|
#
|
||
|
|
# Process a specific directory:
|
||
|
|
# ./rename-images-by-date.sh /path/to/images
|
||
|
|
#
|
||
|
|
# Examples:
|
||
|
|
#
|
||
|
|
# ./rename-images-by-date.sh ~/Pictures
|
||
|
|
#
|
||
|
|
# Result:
|
||
|
|
#
|
||
|
|
# Before:
|
||
|
|
# DSC00123.JPG
|
||
|
|
# Vacation.png
|
||
|
|
#
|
||
|
|
# After:
|
||
|
|
# IMG_20230821_143210.JPG
|
||
|
|
# IMG_20240106_094533.png
|
||
|
|
#
|
||
|
|
# Notes:
|
||
|
|
# - Uses EXIF DateTimeOriginal when available.
|
||
|
|
# - Falls back to the file modification time when EXIF metadata is
|
||
|
|
# missing.
|
||
|
|
# - Preserves the original file extension.
|
||
|
|
# - Prevents overwriting existing files.
|
||
|
|
#
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
# Change to target directory
|
||
|
|
TARGET_DIR="./"
|
||
|
|
|
||
|
|
if [[ -n "$1" ]]; then
|
||
|
|
TARGET_DIR="$1"
|
||
|
|
fi
|
||
|
|
|
||
|
|
cd "$TARGET_DIR" || exit 1
|
||
|
|
|
||
|
|
for file in *.{jpg,jpeg,JPG,JPEG,png,PNG}; do
|
||
|
|
|
||
|
|
# Skip non-existing matches
|
||
|
|
[ -f "$file" ] || continue
|
||
|
|
|
||
|
|
# Extract original capture timestamp from EXIF metadata
|
||
|
|
datetime=$(exiftool -DateTimeOriginal -s3 "$file")
|
||
|
|
|
||
|
|
if [[ -n "$datetime" ]]; then
|
||
|
|
|
||
|
|
# Convert:
|
||
|
|
# 2023:08:21 14:32:10
|
||
|
|
# into:
|
||
|
|
# 20230821_143210
|
||
|
|
formatted=$(
|
||
|
|
echo "$datetime" |
|
||
|
|
sed 's/://g' |
|
||
|
|
sed 's/ /_/g' |
|
||
|
|
cut -c1-15
|
||
|
|
)
|
||
|
|
|
||
|
|
echo "$formatted"
|
||
|
|
|
||
|
|
else
|
||
|
|
|
||
|
|
# Fallback: use file modification timestamp
|
||
|
|
formatted=$(date -r "$file" +"%Y%m%d_%H%M%S")
|
||
|
|
|
||
|
|
fi
|
||
|
|
|
||
|
|
extension="${file##*.}"
|
||
|
|
|
||
|
|
newname="IMG_${formatted}.${extension}"
|
||
|
|
|
||
|
|
# Prevent overwriting existing files
|
||
|
|
if [[ -e "$newname" ]]; then
|
||
|
|
|
||
|
|
i=1
|
||
|
|
|
||
|
|
while [[ -e "IMG_${formatted}_$i.${extension}" ]]; do
|
||
|
|
((i++))
|
||
|
|
done
|
||
|
|
|
||
|
|
newname="IMG_${formatted}_$i.${extension}"
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "Renaming: '$file' -> '$newname'"
|
||
|
|
|
||
|
|
mv "$file" "$newname"
|
||
|
|
|
||
|
|
done
|