Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save DonRichards/f7d421d6ac86ee1b2fcf4a62caf303cc to your computer and use it in GitHub Desktop.

Select an option

Save DonRichards/f7d421d6ac86ee1b2fcf4a62caf303cc to your computer and use it in GitHub Desktop.
Fix Google Photos Takeout Timestamp Issues for Immich

Photo Timestamp Fixer for Google Photos Takeout

I rewrote a lot of this after looking at the script on https://github.com/werner-j/immich-datetime-fix/ Thanks for the help!

A bash script to restore original timestamps from Google Photos Takeout exports by reading .supplemental-metadata.json files and updating EXIF metadata in place.

Problem: Google Photos Takeout exports modify file timestamps during the zip process, breaking chronological sorting in photo management apps like Immich. While Google includes the original timestamps in .supplemental-metadata.json files, most apps ignore these.

Solution: This script restores original timestamps from Google's metadata files to EXIF data, enabling proper date-based sorting and organization without moving or copying files.

Features

  • In-place processing - No file copying or moving
  • Google Photos metadata support - Reads .supplemental-metadata.json files
  • Multiple file format support - JPEG, TIFF, PNG, RAW files (CR2, NEF, ARW, etc.), MP4, MOV, AVI, etc.
  • Progress tracking - Real-time progress bar and statistics
  • Comprehensive logging - Optional detailed logging
  • Flexible filtering - Exclude patterns and custom find options
  • Help system - Built-in help with examples

Requirements

  • exiftool - for EXIF metadata manipulation
  • jq - for JSON parsing

Installation

  1. Download the script: wget https://gist.github.com/DonRichards/f7d421d6ac86ee1b2fcf4a62caf303cc#file-update_timestamps-sh
  2. Make it executable: chmod +x update_dates.sh

Usage

Basic Usage

./update_dates.sh /path/to/your/photos

With Logging

./update_dates.sh /path/to/your/photos -l processing.log

Exclude Patterns

./update_dates.sh /path/to/your/photos -e .DS_Store -e Thumbs.db

Limit to Specific File Types

FIND_OPTS='-iname "*.jpg" -o -iname "*.mp4"' ./update_dates.sh /path/to/your/photos

Show Help

./update_dates.sh --help

How It Works

  1. Scans the source directory for image/video files
  2. Looks for .supplemental-metadata.json files with the same name as each image/video
  3. Extracts original timestamps from the metadata using jq
  4. Updates EXIF data in the original files using exiftool
  5. Provides progress tracking and statistics

File Types Supported

Photos

  • JPEG, TIFF, PNG
  • RAW formats: CR2, NEF, ARW, DNG, RAF, ORF, PEF, RW2

Videos

  • MP4, MOV, AVI, MKV, WEBM, 3GP, M4V

EXIF Tags Updated

  • Photos: DateTimeOriginal (primary), CreateDate (fallback)
  • Videos: CreationDate, MediaCreateDate
  • Other files: CreateDate, ModifyDate

Examples

Process Google Photos Takeout

./update_dates.sh "/path/to/Google Photos Backup/Takeout"

Process with Progress Logging

./update_dates.sh "/path/to/photos" -l timestamp_fix.log

Process Only Specific File Types

FIND_OPTS='-iname "*.jpg" -o -iname "*.cr2"' ./update_dates.sh "/path/to/photos"

Perfect For

  • Immich users importing Google Photos exports
  • Photo management apps that rely on EXIF timestamps
  • Bulk EXIF timestamp correction
  • Restoring original timestamps after Google Photos Takeout

Safety Features

  • In-place processing - No files are moved or copied
  • Original file preservation - Only EXIF metadata is modified
  • Progress tracking - See exactly what's being processed
  • Detailed logging - Optional comprehensive logs

Troubleshooting

Common Issues

"exiftool not found"

# Ubuntu/Debian
sudo apt install exiftool

# CentOS/RHEL
sudo yum install perl-Image-ExifTool

# macOS
brew install exiftool

"jq not found"

# Ubuntu/Debian
sudo apt install jq

# CentOS/RHEL
sudo yum install jq

# macOS
brew install jq

Permission denied

chmod +x update_dates.sh

Statistics

The script provides detailed statistics including:

  • Files with existing timestamps
  • Files that needed timestamp updates
  • Most commonly used EXIF tags
  • File types processed
  • Processing progress

Contributing

Feel free to submit issues and enhancement requests!

License

This project is open source and available under the MIT License.


⚠️ Important: Always backup your photos before running any bulk modification script!

#!/bin/bash
# Check if enough arguments are provided
main() {
check_dependencies
parse_arguments "$@"
init_log
check_folders
initialize_statistics
start_processing
display_final_statistics
log_final_statistics
show_exit_prompt
}
check_dependencies() {
local missing_deps=()
# Check for exiftool
if ! command -v exiftool &> /dev/null; then
missing_deps+=("exiftool")
fi
# Check for jq
if ! command -v jq &> /dev/null; then
missing_deps+=("jq")
fi
# If any dependencies are missing, show error and exit
if [ ${#missing_deps[@]} -gt 0 ]; then
echo -e "\e[31m❌ Missing required dependencies:\e[0m"
for dep in "${missing_deps[@]}"; do
echo -e " \e[33m• $dep\e[0m"
done
echo ""
echo -e "\e[32m📦 Installation instructions:\e[0m"
echo ""
echo -e "\e[37mUbuntu/Debian:\e[0m"
echo -e " sudo apt update && sudo apt install exiftool jq"
echo ""
echo -e "\e[37mCentOS/RHEL/Fedora:\e[0m"
echo -e " sudo yum install perl-Image-ExifTool jq"
echo ""
echo -e "\e[37mmacOS (with Homebrew):\e[0m"
echo -e " brew install exiftool jq"
echo ""
echo -e "\e[37mArch Linux:\e[0m"
echo -e " sudo pacman -S perl-image-exiftool jq"
echo ""
echo -e "\e[37mOpenSUSE:\e[0m"
echo -e " sudo zypper install perl-Image-ExifTool jq"
echo ""
echo -e "\e[33m💡 After installing, run the script again.\e[0m"
exit 1
fi
echo -e "\e[32m✅ All dependencies are installed\e[0m"
}
parse_arguments() {
exclude_patterns=()
# Check for help flag first
for arg in "$@"; do
if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
show_help
exit 0
fi
done
if [ "$#" -lt 1 ]; then
echo -e "\e[31mUsage: $0 srcfolder [-l logfile.log] [-e exclude_pattern]... \e[0m"
echo -e "\e[33mParameters:\e[0m"
echo -e " srcfolder Source directory containing files to process."
echo -e "\e[33mOptions:\e[0m"
echo -e " -l logfile.log Specify a log file to store processing information."
echo -e " -e exclude_pattern Exclude files or directories that match the pattern (can be used multiple times)."
echo -e "\e[33mVariables:\e[0m"
echo -e " FIND_OPTS Specify additional options for the find command (e.g., size limits, excluding specific directories) over the command line variable FIND_OPTS."
echo -e "\e[33mHelp:\e[0m"
echo -e " --help, -h Show this help message."
exit 1
fi
srcfolder=$1
logfile=""
shift 1
while getopts "l:e:o:h" opt; do
case $opt in
e)
exclude_patterns+=($OPTARG)
;;
l)
logfile=$OPTARG
;;
h)
show_help
exit 0
;;
*)
echo -e "\e[31mUsage: $0 srcfolder [-l logfile.log]\e[0m"
exit 1
;;
esac
done
}
show_help() {
echo -e "\e[33m=========================================\e[0m"
echo -e "\e[32m Photo Timestamp Fixer\e[0m"
echo -e "\e[33m=========================================\e[0m"
echo ""
echo -e "\e[37mThis script processes Google Photos Takeout files to restore original timestamps.\e[0m"
echo -e "\e[37mIt reads .supplemental-metadata.json files and applies the original timestamps to:\e[0m"
echo -e "\e[37m1. EXIF metadata (DateTimeOriginal for photos, CreationDate for videos)\e[0m"
echo -e "\e[37m2. Handles various file types: JPG, CR2, RAW, MP4, MOV, etc.\e[0m"
echo ""
echo -e "\e[32mUsage:\e[0m"
echo -e " $0 \e[33msrcfolder\e[0m [\e[33moptions\e[0m]"
echo ""
echo -e "\e[32mParameters:\e[0m"
echo -e " \e[33msrcfolder\e[0m Source directory containing files to process"
echo ""
echo -e "\e[32mOptions:\e[0m"
echo -e " \e[33m-l logfile.log\e[0m Specify a log file to store processing information"
echo -e " \e[33m-e exclude_pattern\e[0m Exclude files or directories that match the pattern"
echo -e " (can be used multiple times)"
echo -e " \e[33m-h, --help\e[0m Show this help message"
echo ""
echo -e "\e[32mEnvironment Variables:\e[0m"
echo -e " \e[33mFIND_OPTS\e[0m Specify additional options for the find command"
echo -e " (e.g., size limits, excluding specific directories)"
echo ""
echo -e "\e[32mExamples:\e[0m"
echo -e " \e[37m# Basic usage\e[0m"
echo -e " $0 /path/to/photos"
echo ""
echo -e " \e[37m# With logging\e[0m"
echo -e " $0 /path/to/photos -l processing.log"
echo ""
echo -e " \e[37m# Exclude certain patterns\e[0m"
echo -e " $0 /path/to/photos -e .DS_Store -e Thumbs.db"
echo ""
echo -e " \e[37m# Limit to specific file types\e[0m"
echo -e " FIND_OPTS='-iname \"*.jpg\" -o -iname \"*.mp4\"' $0 /path/to/photos"
echo ""
echo -e "\e[32mRequirements:\e[0m"
echo -e " \e[37m• exiftool\e[0m - For reading and writing EXIF metadata"
echo -e " \e[37m• jq\e[0m - For parsing JSON metadata files"
echo ""
echo -e "\e[32mHow it works:\e[0m"
echo -e " 1. \e[37mScans the source directory for image/video files\e[0m"
echo -e " 2. \e[37mLooks for .supplemental-metadata.json files with the same name\e[0m"
echo -e " 3. \e[37mExtracts original timestamps from the metadata\e[0m"
echo -e " 4. \e[37mUpdates EXIF data in the original files (in place)\e[0m"
echo -e " 5. \e[37mProvides progress tracking and statistics\e[0m"
echo ""
echo -e "\e[33m=========================================\e[0m"
}
init_log() {
if [ -n "$logfile" ]; then
echo "=========================================" >> "$logfile"
echo "Processing started: $(date '+%Y-%m-%d %H:%M:%S')" >> "$logfile"
echo "=========================================" >> "$logfile"
fi
}
check_folders() {
if [ ! -d "$srcfolder" ]; then
echo -e "\e[31mSource folder does not exist\e[0m"
exit 1
fi
# No need to create subdirectories since we're processing in place
}
initialize_statistics() {
# Build exclude pattern arguments for find command
exclude_args=()
for pattern in "${exclude_patterns[@]}"; do
exclude_args+=" -not -ipath \"*$pattern*\" "
done
files_with_tags=0
files_without_tags=0
find_command="find \"$srcfolder\" $FIND_OPTS -type f ${exclude_args[@]} -print"
if [ -n "$logfile" ]; then
echo "Find command used for discovering files: $find_command" >> "$logfile"
fi
total_files=$(eval $find_command | wc -l)
if [ -n "$logfile" ]; then
echo "Total files found: $total_files" >> "$logfile"
fi
current_file=0
declare -gA tag_usage
declare -gA filetype_count
tmpfile=$(mktemp)
trap "rm -f $tmpfile" EXIT
# Colors for UI
title_color="\e[33m"
text_color="\e[37m"
progress_color="\e[32m"
box_color="\e[33m"
header_color="\e[32m"
reset_color="\e[0m"
}
# Function to get the best available date from a file
get_best_date() {
local file="$1"
local date=""
local used_tag=""
# Try to get DateTimeOriginal first (most reliable for photos)
date=$(exiftool -s3 -DateTimeOriginal "$file" 2>/dev/null)
if [ -n "$date" ]; then
used_tag="DateTimeOriginal"
echo "$date|$used_tag"
return 0
fi
# Try SubSecDateTimeOriginal
date=$(exiftool -s3 -SubSecDateTimeOriginal "$file" 2>/dev/null)
if [ -n "$date" ]; then
used_tag="SubSecDateTimeOriginal"
echo "$date|$used_tag"
return 0
fi
# Try CreateDate
date=$(exiftool -s3 -CreateDate "$file" 2>/dev/null)
if [ -n "$date" ]; then
used_tag="CreateDate"
echo "$date|$used_tag"
return 0
fi
# Try SubSecCreateDate
date=$(exiftool -s3 -SubSecCreateDate "$file" 2>/dev/null)
if [ -n "$date" ]; then
used_tag="SubSecCreateDate"
echo "$date|$used_tag"
return 0
fi
# Try MediaCreateDate (for videos)
date=$(exiftool -s3 -MediaCreateDate "$file" 2>/dev/null)
if [ -n "$date" ]; then
used_tag="MediaCreateDate"
echo "$date|$used_tag"
return 0
fi
# Try SubSecMediaCreateDate
date=$(exiftool -s3 -SubSecMediaCreateDate "$file" 2>/dev/null)
if [ -n "$date" ]; then
used_tag="SubSecMediaCreateDate"
echo "$date|$used_tag"
return 0
fi
# Try GPSDateTime
date=$(exiftool -s3 -GPSDateTime "$file" 2>/dev/null)
if [ -n "$date" ]; then
used_tag="GPSDateTime"
echo "$date|$used_tag"
return 0
fi
# Try ModifyDate
date=$(exiftool -s3 -ModifyDate "$file" 2>/dev/null)
if [ -n "$date" ]; then
used_tag="ModifyDate"
echo "$date|$used_tag"
return 0
fi
# Try SubSecModifyDate
date=$(exiftool -s3 -SubSecModifyDate "$file" 2>/dev/null)
if [ -n "$date" ]; then
used_tag="SubSecModifyDate"
echo "$date|$used_tag"
return 0
fi
# Try GPSDateStamp
date=$(exiftool -s3 -GPSDateStamp "$file" 2>/dev/null)
if [ -n "$date" ]; then
used_tag="GPSDateStamp"
echo "$date|$used_tag"
return 0
fi
# Try FileModifyDate (filesystem date)
date=$(exiftool -s3 -FileModifyDate "$file" 2>/dev/null)
if [ -n "$date" ]; then
used_tag="FileModifyDate"
echo "$date|$used_tag"
return 0
fi
# If no date found, return empty
echo "|"
return 1
}
# Function to get date from Google Photos supplemental metadata
get_date_from_metadata() {
local file="$1"
local json_file="${file}.supplemental-metadata.json"
if [ -f "$json_file" ]; then
# Extract timestamp from JSON
local ts=$(jq -r '.photoTakenTime.timestamp' "$json_file" 2>/dev/null)
if [[ "$ts" =~ ^[0-9]+$ ]]; then
# Convert timestamp to EXIF format
local exif_date=$(date -u -d @"$ts" +"%Y:%m:%d %H:%M:%S" 2>/dev/null)
if [ -n "$exif_date" ]; then
echo "$exif_date|GooglePhotosMetadata"
return 0
fi
fi
fi
# If no metadata file or invalid timestamp, return empty
echo "|"
return 1
}
# Function to normalize date format for EXIF
normalize_date_for_exif() {
local date="$1"
# Remove timezone info if present
date=$(echo "$date" | sed 's/[-+][0-9][0-9]:[0-9][0-9]$//')
# Convert various formats to EXIF format (YYYY:MM:DD HH:MM:SS)
# Handle ISO format: 2023-01-15T14:30:00
if [[ "$date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2} ]]; then
echo "$date" | sed 's/T/ /' | sed 's/-/:/g'
return 0
fi
# Handle standard format: 2023-01-15 14:30:00
if [[ "$date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}[[:space:]][0-9]{2}:[0-9]{2}:[0-9]{2} ]]; then
echo "$date" | sed 's/-/:/g'
return 0
fi
# Handle EXIF format: 2023:01:15 14:30:00
if [[ "$date" =~ ^[0-9]{4}:[0-9]{2}:[0-9]{2}[[:space:]][0-9]{2}:[0-9]{2}:[0-9]{2} ]]; then
echo "$date"
return 0
fi
# Handle date only: 2023-01-15
if [[ "$date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
echo "$date" | sed 's/-/:/g' | sed 's/$/ 00:00:00/'
return 0
fi
# If we can't parse it, return as is
echo "$date"
}
# Function to set EXIF date based on file type
set_exif_date() {
local file="$1"
local date="$2"
local file_type="$3"
# Normalize the date for EXIF
local exif_date=$(normalize_date_for_exif "$date")
case "$file_type" in
"JPEG"|"TIFF"|"PNG"|"CR2"|"NEF"|"ARW"|"DNG"|"RAF"|"ORF"|"PEF"|"RW2")
# For photos, use DateTimeOriginal
if exiftool -q -overwrite_original -DateTimeOriginal="$exif_date" "$file" 2>/dev/null; then
return 0
else
# Fallback to CreateDate if DateTimeOriginal fails
exiftool -q -overwrite_original -CreateDate="$exif_date" -ModifyDate="$exif_date" "$file" 2>/dev/null
return $?
fi
;;
"MP4"|"MOV"|"AVI"|"MKV"|"WEBM"|"3GP"|"M4V")
# For videos, use CreationDate and MediaCreateDate
exiftool -q -overwrite_original -CreationDate="$exif_date" -MediaCreateDate="$exif_date" "$file" 2>/dev/null
return $?
;;
*)
# For other files, try general date tags
exiftool -q -overwrite_original -CreateDate="$exif_date" -ModifyDate="$exif_date" "$file" 2>/dev/null
return $?
;;
esac
}
frame() {
clear
echo -e "${box_color}####################################################${reset_color}"
echo -e "${box_color}# #${reset_color}"
echo -e "${header_color}# Photo Timestamp Fixer #${reset_color}"
echo -e "${box_color}# #${reset_color}"
echo -e "${box_color}####################################################${reset_color}"
}
show_progress() {
frame
echo -e "${progress_color}Processing files... ($current_file/$total_files)${reset_color}"
progress_percent=$(( (current_file * 100) / total_files ))
progress_bar=$(printf "[%-50s]" $(eval "printf '='%.0s {1..$(( progress_percent / 2 ))}"))
echo -e "${progress_color}Progress: ${progress_bar} ${progress_percent}%${reset_color}"
# Multi-column layout for statistics
echo -e "${box_color}----------------------------------------------------${reset_color}"
echo -e "${header_color}Statistics:${reset_color}"
echo -e "${text_color}Files with tags : $files_with_tags${reset_color}"
echo -e "${text_color}Files without tags : $files_without_tags${reset_color}"
echo -e "${box_color}----------------------------------------------------${reset_color}"
# Tag statistics
if [ ${#tag_usage[@]} -gt 0 ]; then
echo -e "${header_color}Most used tags:${reset_color}"
for tag in "${!tag_usage[@]}"; do
echo -e "${text_color}$tag: ${tag_usage[$tag]}${reset_color}"
done
else
echo -e "${text_color}No tags were found.${reset_color}"
fi
echo -e "${box_color}----------------------------------------------------${reset_color}"
# File types processed
if [ ${#filetype_count[@]} -gt 0 ]; then
echo -e "${header_color}File types processed:${reset_color}"
for ext in "${!filetype_count[@]}"; do
echo -e "${text_color}$ext: ${filetype_count[$ext]}${reset_color}"
done
else
echo -e "${text_color}No files were processed.${reset_color}"
fi
echo -e "${box_color}----------------------------------------------------${reset_color}"
# Last processed files
echo -e "${header_color}Last processed files:${reset_color}"
tail -n 10 "$tmpfile"
echo -e "${box_color}----------------------------------------------------${reset_color}"
}
start_processing() {
# Build exclude pattern arguments for find command
exclude_args=()
for pattern in "${exclude_patterns[@]}"; do
exclude_args+=" -not -ipath \"*$pattern*\" "
done
find_command="find \"$srcfolder\" $FIND_OPTS -type f ! -iname ".*" ${exclude_args[@]} -print"
if [ -n "$logfile" ]; then
echo "Find command used for discovering files: $find_command" >> "$logfile"
fi
total_files=$(eval $find_command | wc -l)
while IFS= read -r file; do
((current_file++))
process_file "$file"
show_progress
done < <(eval $find_command)
}
process_file() {
local file=$1
extension="${file##*.}"
((filetype_count[${extension,,}]++))
# First try to get date from Google Photos metadata file
local date_info=$(get_date_from_metadata "$file")
local datetime=$(echo "$date_info" | cut -d'|' -f1)
local used_tag=$(echo "$date_info" | cut -d'|' -f2)
# If no metadata file found, try to get date from EXIF
if [ -z "$datetime" ]; then
date_info=$(get_best_date "$file")
datetime=$(echo "$date_info" | cut -d'|' -f1)
used_tag=$(echo "$date_info" | cut -d'|' -f2)
fi
local tag_status=""
if [ -n "$datetime" ]; then
# File has date information
((files_with_tags++))
tag_status="Tag present"
# Track tag usage
if [ -n "$used_tag" ]; then
((tag_usage[$used_tag]++))
fi
else
# File has no date information - use current date as fallback
((files_without_tags++))
tag_status="Tag added"
datetime=$(date '+%Y:%m:%d %H:%M:%S')
used_tag="CurrentDate"
fi
# Detect file type for proper EXIF handling
local file_type=$(exiftool -FileType -b "$file" 2>/dev/null)
if [ -z "$file_type" ]; then
# Fallback to extension-based detection
case "${extension,,}" in
jpg|jpeg|tiff|png|cr2|nef|arw|dng|raf|orf|pef|rw2)
file_type="JPEG"
;;
mp4|mov|avi|mkv|webm|3gp|m4v)
file_type="MP4"
;;
*)
file_type="Unknown"
;;
esac
fi
# Update EXIF data if needed
if [ "$tag_status" == "Tag added" ]; then
if set_exif_date "$file" "$datetime" "$file_type"; then
tag_status="Tag added (EXIF updated)"
else
tag_status="Tag added (EXIF failed)"
fi
fi
output_line="$(date '+%b %d %H:%M:%S') INFO: $file - EXIF DateTime: $datetime, Status: $tag_status, Used Tag: $used_tag"
echo "$output_line" >> "$tmpfile"
if [ -n "$logfile" ]; then
echo "$output_line" >> "$logfile"
fi
}
display_final_statistics() {
frame
echo -e "${progress_color}Processing completed. Files updated in place with timestamps if needed.${reset_color}"
echo -e "${text_color}Files with proper tags: $files_with_tags${reset_color}"
echo -e "${text_color}Files without tags: $files_without_tags${reset_color}"
# Display most used tags and file types
echo -e "${box_color}----------------------------------------------------${reset_color}"
if [ ${#tag_usage[@]} -gt 0 ]; then
echo -e "${header_color}Most used tags:${reset_color}"
for tag in "${!tag_usage[@]}"; do
echo -e "${text_color}$tag: ${tag_usage[$tag]}${reset_color}"
done
else
echo -e "${text_color}No tags were found.${reset_color}"
fi
echo -e "${box_color}----------------------------------------------------${reset_color}"
if [ ${#filetype_count[@]} -gt 0 ]; then
echo -e "${header_color}File types processed:${reset_color}"
for ext in "${!filetype_count[@]}"; do
echo -e "${text_color}$ext: ${filetype_count[$ext]}${reset_color}"
done
else
echo -e "${text_color}No files were processed.${reset_color}"
fi
echo -e "${box_color}----------------------------------------------------${reset_color}"
}
show_exit_prompt() {
# Check if tput is available
if command -v tput > /dev/null 2>&1; then
# Centered overlay exit prompt using tput
cols=$(tput cols)
rows=$(tput lines)
msg="Press any key to exit..."
msg_length=${#msg}
x=$(( (cols - 38) / 2 ))
y=$(( (rows / 2) - 1 ))
# Move cursor to the calculated position and display the box
tput cup $y $x
echo -e "${box_color}####################################${reset_color}"
tput cup $((y + 1)) $x
echo -e "${box_color}#${reset_color} ${text_color}${msg}${reset_color} ${box_color}#${reset_color}"
tput cup $((y + 2)) $x
echo -e "${box_color}####################################${reset_color}"
tput cup $((y + 4)) 0
else
# Simple exit prompt if tput is not available
echo -e "${box_color}####################################${reset_color}"
echo -e "${box_color}#${reset_color} ${text_color}Press any key to exit...${reset_color} ${box_color}#${reset_color}"
echo -e "${box_color}####################################${reset_color}"
fi
read -n 1 -s
}
log_final_statistics() {
if [ -n "$logfile" ]; then
echo "=========================================" >> "$logfile"
echo "Processing completed. Files updated in place with timestamps if needed." >> "$logfile"
echo "=========================================" >> "$logfile"
echo "Processing ended: $(date '+%Y-%m-%d %H:%M:%S')" >> "$logfile"
echo "=========================================" >> "$logfile"
echo "Files with proper tags: $files_with_tags" >> "$logfile"
echo "Files without tags: $files_without_tags" >> "$logfile"
echo "Most used tags:" >> "$logfile"
for tag in "${!tag_usage[@]}"; do
echo "$tag: ${tag_usage[$tag]}" >> "$logfile"
done
echo "File types processed:" >> "$logfile"
for ext in "${!filetype_count[@]}"; do
echo "$ext: ${filetype_count[$ext]}" >> "$logfile"
done
fi
}
# Run the main function
main "$@"
@DonRichards
Copy link
Author

Even with the dates changes, it doesn't seem to matter at the moment. The dates aren't respected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment