Files
2026-05-12 12:27:32 -04:00

62 lines
1.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Usage:
# ./move-numbered-copies.sh /music /music/copy-root
#
# Example:
# ./move-numbered-copies.sh /music/library /music/copies
#
# Optional dry run:
# DRY_RUN=1 ./move-numbered-copies.sh /music/library /music/copies
SRC_ROOT="${1:-/music/incoming}"
COPY_ROOT="${2:-/music/incoming-unknown}"
DRY_RUN="${DRY_RUN:-0}"
# Remove trailing slashes for consistency
SRC_ROOT="${SRC_ROOT%/}"
COPY_ROOT="${COPY_ROOT%/}"
if [[ ! -d "$SRC_ROOT" ]]; then
echo "Source root does not exist: $SRC_ROOT" >&2
exit 1
fi
mkdir -p "$COPY_ROOT"
find "$SRC_ROOT" -type f -print0 |
while IFS= read -r -d '' file; do
base="$(basename "$file")"
# Match names like:
# Name (1).flac
# Name(2).mp3
# Anything (123).m4a
if [[ "$base" =~ \([0-9]+\)\.[^./]+$ ]]; then
rel="${file#"$SRC_ROOT"/}"
dest="$COPY_ROOT/$rel"
dest_dir="$(dirname "$dest")"
mkdir -p "$dest_dir"
# Avoid overwriting if the destination already exists
if [[ -e "$dest" ]]; then
name="${dest%.*}"
ext="${dest##*.}"
i=1
while [[ -e "${name}.moved${i}.${ext}" ]]; do
((i++))
done
dest="${name}.moved${i}.${ext}"
fi
if [[ "$DRY_RUN" == "1" ]]; then
printf 'Would move: %s -> %s\n' "$file" "$dest"
else
printf 'Moving: %s -> %s\n' "$file" "$dest"
mv -- "$file" "$dest"
fi
fi
done