#!/bin/bash # # sync-newer-images — For each top-level image or video in SRC, copy it to # DEST if it doesn't already exist anywhere under DEST. # Works on Linux and macOS (bash 3.2+ compatible). usage() { cat <<'EOF' Usage: sync-newer-images [options] For each top-level image or video in source, copy it into destination if no file with the same name exists anywhere under destination. Options: -u, --update If a matching file already exists under destination, copy over it only if the content differs (uses cmp). -h, --help Show this help message and exit EOF exit 0 } update_mode=0 while [ $# -gt 0 ]; do case "$1" in -h|--help) usage ;; -u|--update) update_mode=1; shift ;; *) break ;; esac done if [ $# -lt 2 ]; then echo "Error: destination and source are required" >&2 echo "Usage: sync-newer-images [options] " >&2 exit 1 fi DEST="$1" SRC="$2" if [ ! -d "$DEST" ]; then echo "Error: destination '$DEST' is not a directory" >&2 exit 1 fi if [ ! -d "$SRC" ]; then echo "Error: source '$SRC' is not a directory" >&2 exit 1 fi # Build deduplicated, newline-separated list of all basenames under DEST. basenames=$(find "$DEST" -type f 2>/dev/null | sed 's|.*/||' | sort -u) copied=0 for srcfile in "$SRC"/*; do [ -f "$srcfile" ] || continue ext="${srcfile##*.}" case "$(echo "$ext" | tr '[:upper:]' '[:lower:]')" in jpg|jpeg|png|gif|heic|webp|bmp|tiff|tif) ;; mov|mp4|m4v|avi|mkv|3gp) ;; *) continue ;; esac filename="${srcfile##*/}" if ! printf '%s\n' "$basenames" | grep -qxF "$filename"; then cp -v "$srcfile" "$DEST/" copied=$((copied + 1)) elif [ "$update_mode" -eq 1 ]; then destfile=$(find "$DEST" -type f -name "$filename" 2>/dev/null | head -1) if [ -n "$destfile" ] && ! cmp -s "$srcfile" "$destfile"; then cp -v "$srcfile" "$destfile" copied=$((copied + 1)) fi fi done echo "Copied ${copied} image(s)/video(s) from ${SRC} into ${DEST}"