62 lines
1.4 KiB
Bash
Executable File
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
|