Skip to content

Instantly share code, notes, and snippets.

@max-mapper
Created March 3, 2026 11:41
Show Gist options
  • Select an option

  • Save max-mapper/4958e9fc924e6cddafdd6813cdbf161f to your computer and use it in GitHub Desktop.

Select an option

Save max-mapper/4958e9fc924e6cddafdd6813cdbf161f to your computer and use it in GitHub Desktop.
photo renaming scripts
#!/bin/bash
# Ensure heif-convert is installed
if ! command -v heif-convert &> /dev/null; then
echo "Error: 'heif-convert' is not installed."
echo "Please install it (e.g., sudo apt install libheif-examples) and try again."
exit 1
fi
TARGET_DIR="${1:-.}"
echo "Scanning files in '$TARGET_DIR' for disguised HEIF images..."
# Loop through all files in the target directory
for filepath in "$TARGET_DIR"/*; do
# Ensure it's a file
if [[ -f "$filepath" ]]; then
# Check if the internal file signature matches HEIF/HEVC
if file "$filepath" | grep -qi "HEIF Image"; then
echo "Converting: $(basename "$filepath")"
# 1. Convert to a temporary file first to ensure the process doesn't corrupt the original
temp_file="${filepath}.tmp.jpg"
# -q 95 sets the JPEG quality to 95%. Adjust if you want smaller/larger file sizes.
if heif-convert -q 95 "$filepath" "$temp_file" >/dev/null 2>&1; then
# 2. Figure out the final correct filename (enforcing a .jpg extension)
dir=$(dirname "$filepath")
base=$(basename "$filepath")
name="${base%.*}" # Strips the old extension
final_file="$dir/$name.jpg"
# 3. Overwrite the final destination with the new true JPEG
mv "$temp_file" "$final_file"
echo " -> Success: Saved as $(basename "$final_file")"
# 4. If the original file had a different name (e.g., .HEIC instead of .jpg), delete the old one
if [[ "$filepath" != "$final_file" ]]; then
rm "$filepath"
fi
else
echo " -> Failed to convert $(basename "$filepath")"
# Clean up the broken temp file if the conversion failed
rm -f "$temp_file"
fi
fi
fi
done
echo "Done!"
#!/bin/bash
for file in *.heic; do
mv "$file" "${file%.heic}.jpg"
done
for file in *.HEIC; do
mv "$file" "${file%.HEIC}.jpg"
done
#!/bin/bash
# Ensure exiftool is installed before proceeding
if ! command -v exiftool &> /dev/null; then
echo "Error: 'exiftool' is not installed."
exit 1
fi
# Use the provided directory or default to the current directory
TARGET_DIR="${1:-.}"
# Verify the target directory exists
if [[ ! -d "$TARGET_DIR" ]]; then
echo "Error: Directory '$TARGET_DIR' not found."
exit 1
fi
echo "Scanning '$TARGET_DIR' for images..."
# Loop through common image files safely
find "$TARGET_DIR" -maxdepth 1 -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.heic" \) | while read -r file; do
# THE WATERFALL METHOD:
# Exiftool requests multiple date tags. It outputs them in the exact order requested.
# 1. DateTimeOriginal (Primary EXIF)
# 2. CreateDate (Secondary EXIF/XMP)
# 3. ModifyDate (Tertiary EXIF/XMP)
# 4. GPSDateTime (Time from GPS coordinates)
# 5. FileModifyDate (The OS-level file modification time - Ultimate fallback)
# 'head -n 1' isolates the first (and therefore best) available date.
creation_date=$(exiftool -d "%Y%m%d_%H%M%S" -DateTimeOriginal -CreateDate -ModifyDate -GPSDateTime -FileModifyDate -S -s "$file" | head -n 1)
if [[ -n "$creation_date" ]]; then
# Extract the original file extension and convert it to lowercase
ext="${file##*.}"
ext="${ext,,}"
# Define the base new filename
new_name="${TARGET_DIR}/${creation_date}.${ext}"
# Collision Handling
counter=1
while [[ -e "$new_name" && "$file" != "$new_name" ]]; do
new_name="${TARGET_DIR}/${creation_date}_$(printf "%03d" $counter).${ext}"
((counter++))
done
# Rename the file if the name has actually changed
if [[ "$file" != "$new_name" ]]; then
mv "$file" "$new_name"
echo "Renamed: $(basename "$file") -> $(basename "$new_name")"
fi
else
# Because we included FileModifyDate, this skip will almost never happen,
# but it's here for safety.
echo "Skipped: $(basename "$file") (No date data found at all)"
fi
done
echo "Renaming complete."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment