Last active
June 18, 2026 16:40
-
-
Save neo22s/c7b49b4f737ec5ab7a5129ac189cc77a to your computer and use it in GitHub Desktop.
Adds a 1-star rating (XMP:Rating=1) to all specified JPG/JPEG/DNG/RAW files (case-insensitive), only if not already rated.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # ===================================================== | |
| # Script: rate.sh | |
| # Purpose: Adds a star rating (XMP:Rating + EXIF:Rating) to all | |
| # specified JPG/JPEG/DNG/RAW files (case-insensitive), | |
| # and optionally to their RAW pairs (CR3, ARW, NEF, etc.). | |
| # | |
| # Usage: | |
| # ./rate.sh IMG_1234.JPG IMG_1235.jpg | |
| # ./rate.sh "IMG_1234.JPG, IMG_1235.jpg" | |
| # ./rate.sh "1Z8A4331 OR 1Z8A4373 OR 1Z8A4378" | |
| # ./rate.sh 1Z8A4331 OR 1Z8A4373 OR 1Z8A4378 | |
| # | |
| # Requires: | |
| # - exiftool | |
| # ===================================================== | |
| RATING_VALUE=1 | |
| RAW_EXTENSIONS=("CR3" "CR2" "ARW" "NEF" "RAF" "ORF" "RW2" "DNG") | |
| if ! command -v exiftool &>/dev/null; then | |
| echo "❌ Error: exiftool is not installed." | |
| exit 1 | |
| fi | |
| if [ $# -eq 0 ]; then | |
| echo "Usage: $0 <item1> <item2> ... OR a quoted comma/OR-separated list" | |
| exit 1 | |
| fi | |
| # Itera argumento por argumento, filtrando "OR" con tr (compatible macOS) | |
| INPUT_ITEMS=() | |
| for arg in "$@"; do | |
| upper=$(echo "$arg" | tr '[:lower:]' '[:upper:]') | |
| [ "$upper" = "OR" ] && continue | |
| cleaned=$(echo "$arg" | tr -d ',') | |
| [ -z "$cleaned" ] && continue | |
| if [[ "$cleaned" == *.* ]]; then | |
| base="${cleaned%.*}" | |
| else | |
| base="$cleaned" | |
| fi | |
| INPUT_ITEMS+=("$base") | |
| done | |
| echo "🔧 Rating ${#INPUT_ITEMS[@]} images with ${RATING_VALUE} stars..." | |
| for base in "${INPUT_ITEMS[@]}"; do | |
| found_any=false | |
| orig_file=$(find . -maxdepth 1 -iname "${base}.*" -type f | grep -iE '\.(jpe?g|dng)$' | head -n1) | |
| if [[ -n "$orig_file" ]]; then | |
| exiftool -m -overwrite_original -quiet \ | |
| -if '$Rating < 1' \ | |
| -XMP:Rating="$RATING_VALUE" \ | |
| -EXIF:Rating="$RATING_VALUE" \ | |
| "$orig_file" | |
| echo "✔️ Rated $(basename "$orig_file")" | |
| found_any=true | |
| else | |
| echo "⚠️ JPG/JPEG/DNG not found for: ${base}" | |
| fi | |
| for ext in "${RAW_EXTENSIONS[@]}"; do | |
| raw_file=$(find . -maxdepth 1 -iname "${base}.${ext}" -type f | head -n1) | |
| if [[ -n "$raw_file" ]]; then | |
| exiftool -m -overwrite_original -quiet \ | |
| -if '$Rating < 1' \ | |
| -XMP:Rating="$RATING_VALUE" \ | |
| -EXIF:Rating="$RATING_VALUE" \ | |
| "$raw_file" | |
| echo "✔️ Rated $(basename "$raw_file")" | |
| found_any=true | |
| fi | |
| done | |
| if [ "$found_any" = false ]; then | |
| echo "⚠️ No files found for base name: $base" | |
| fi | |
| done | |
| echo "✅ Rating complete." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment