#!/usr/bin/env bash set -euo pipefail root="$1" find "$root" -type f \( \ -iname '*.m4b' -o \ -iname '*.m4a' -o \ -iname '*.mp3' -o \ -iname '*.aac' -o \ -iname '*.flac' -o \ -iname '*.ogg' -o \ -iname '*.opus' -o \ -iname '*.wav' -o \ -iname '*.wma' -o \ -iname '*.mp4' \ \) -print0 | while IFS= read -r -d '' file; do rel="${file#"$root"/}" # Only process: book/file # Leave already organized: author/book/file [[ "$rel" == */*/* ]] && continue [[ "$rel" != */* ]] && continue book="${rel%%/*}" name="${rel#*/}" artist="$(ffprobe -v error \ -show_entries format_tags=artist \ -of default=noprint_wrappers=1:nokey=1 \ "$file" 2>/dev/null || true)" # Trim whitespace artist="$(printf '%s' "$artist" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" # No artist tag -> skip [[ -z "$artist" ]] && continue dest="$root/$artist/$book" mkdir -p -- "$dest" echo "Moving: $rel" echo " -> $artist/$book/$name" mv -- "$file" "$dest/$name" done # Remove empty directories find "$root" -depth -type d -empty -delete