#!/bin/bash # Example file structure: # . # ├── jpg # │   ├── 123.jpg # │   ├── 789.jpg # │   └── 890.jpg # └── raw # ├── 123.raw # ├── 456.raw # └── 789.raw # # ❯ ./compare_folders.sh raw jpg # Only in raw: # raw/456.raw # # Only in jpg: # jpg/890.jpg # # ======================================== # WARNING: Deletion is PERMANENT and # UNRECOVERABLE! Files will NOT go to Trash. # ======================================== # # Would you like to delete the unmatched files? # 1) Delete files in raw that are missing in jpg # 2) Delete files in jpg that are missing in raw # 3) Do nothing and exit # # Choose [1/2/3]: # if [ $# -lt 2 ]; then echo "Usage: $0 " exit 1 fi dir1="$1" dir2="$2" # Extract basenames without extensions names1=$(ls "$dir1" | sed 's/\.[^.]*$//' | sort) names2=$(ls "$dir2" | sed 's/\.[^.]*$//' | sort) only_in_1=$(comm -23 <(echo "$names1") <(echo "$names2")) only_in_2=$(comm -13 <(echo "$names1") <(echo "$names2")) if [ -n "$only_in_1" ]; then echo "Only in $dir1:" for name in $only_in_1; do ls "$dir1"/"$name".* 2>/dev/null done echo "" fi if [ -n "$only_in_2" ]; then echo "Only in $dir2:" for name in $only_in_2; do ls "$dir2"/"$name".* 2>/dev/null done echo "" fi if [ -z "$only_in_1" ] && [ -z "$only_in_2" ]; then echo "All file basenames match between the two folders." exit 0 fi # Offer to delete echo "========================================" echo "WARNING: Deletion is PERMANENT and" echo "UNRECOVERABLE! Files will NOT go to Trash." echo "========================================" echo "" echo "Would you like to delete the unmatched files?" echo " 1) Delete files in $dir1 that are missing in $dir2" echo " 2) Delete files in $dir2 that are missing in $dir1" echo " 3) Do nothing and exit" echo "" read -rp "Choose [1/2/3]: " choice case "$choice" in 1) if [ -z "$only_in_1" ]; then echo "No unmatched files in $dir1. Nothing to delete." exit 0 fi echo "" echo "The following files will be PERMANENTLY deleted:" for name in $only_in_1; do ls "$dir1"/"$name".* 2>/dev/null done echo "" read -rp "Are you sure? Type YES to confirm: " confirm if [ "$confirm" = "YES" ]; then for name in $only_in_1; do rm -v "$dir1"/"$name".* 2>/dev/null done echo "Done." else echo "Aborted." fi ;; 2) if [ -z "$only_in_2" ]; then echo "No unmatched files in $dir2. Nothing to delete." exit 0 fi echo "" echo "The following files will be PERMANENTLY deleted:" for name in $only_in_2; do ls "$dir2"/"$name".* 2>/dev/null done echo "" read -rp "Are you sure? Type YES to confirm: " confirm if [ "$confirm" = "YES" ]; then for name in $only_in_2; do rm -v "$dir2"/"$name".* 2>/dev/null done echo "Done." else echo "Aborted." fi ;; *) echo "No files deleted." ;; esac