#!/bin/bash SR=false CONFIRM=false DRY_RUN=false REPAIR_ONLY=false FILES_ONLY=false DIR_ONLY=false DELETE=false CAPITALIZE=false GOTO_PATH=false FILE_PATH=false FILE="" container=("mpg" "avi" "mkv" "mp4" "m4v" "srt") DAMAGE=("\.\." "-\." "\.-" "\(\." "\.\." "-" "_" "\.\[" "\.\(" " " "\[" " \." "\]" "(" "(\.") unwanted_filename_parts=("TV\ Series" "x264" "Complete" "10bit" "\[.*\]" "320kbps" "WS" "AC3" "iNT" "NF\.WEB" "bdrip" "RERIP" "DUAL-" "(ENG" "\[320\]" "rus.eng" "LostFilm" "readnfo" "800p" "BluRay" "Jasprr" "KORSUB" "576p" "720p" "1080p" "1080P" "720P" "WEB" "AMZN" "internal" "iNTERNAL" "HDTV" "KILLERS" "web" "hdtv" "REAL" "DVD" "dvd" "PDTV" "PROPER" "BDRip" "HDRip" "DvD" "480" "INTERNAL" "REPACK" "\[m00tv\]" "\[VFUA\]" "\[PiXTV\]" "\[GOTHiC\]" "\[RiVER\]" "EXTENDED" "SWESUB" "DVB" "XviD" "\[FoV\]" "repack" "BRRip" "UEE" "BrRip" "brrip" "\[SubRip" "UNRATED" "Directors Cut") KNOWN_SHIT_FILES=("www\.YTS*" "Torrent downloaded*\.txt" "Read Me.txt" "WWW.YTS.RE.jpg" "*\.nfo" "RARBG\.com\.txt" "RARBG\.txt" "RARBG\.COM*" "WWW\.YIFY-TORRENTS\.COM\.jpg" "RARBG_DO_NOT_MIRROR\.exe" "Uploaded\ by*") get_config() { while [[ ${1:0:1} == - ]]; do echo "Param: $1" [[ $1 == -r ]] && { SR=true if [ "$2" == "" ] || [ "$3" == "" ]; then echo "Too few arguments"; usage; exit; fi search="$2" replace="$3" shift 3; continue; }; [[ $1 == -path ]] && { GOTO_PATH=true if [ "$2" == "" ] ; then echo "Too few arguments"; usage; exit; fi GOTO="$2" if [ ! -d "${GOTO}" ]; then echo "${GOTO} no valid Path" exit 1; fi shift 2; continue; }; [[ $1 == -file ]] && { FILE_PATH=true if [ "$2" == "" ] ; then echo "Too few arguments"; usage; exit; fi FILE="$2" if [ ! -f "${FILE}" ]; then echo "${FILE} no valid File" exit 1; fi shift 2; continue; }; [[ $1 == -help ]] && { usage; exit; }; [[ $1 == -cap ]] && { CAPITALIZE=true shift 1; continue; }; [[ $1 == -conf ]] && { CONFIRM=true shift 1; continue; }; [[ $1 == -dry ]] && { DRY_RUN=true; shift 1; continue; }; [[ $1 == -dir ]] && { DIR_ONLY=true; shift 1; continue; }; [[ $1 == -files ]] && { FILES_ONLY=true; shift 1; continue; }; [[ $1 == -repair ]] && { REPAIR_ONLY=true; shift 1; continue; }; [[ $1 == -l ]] && { find . -name "*${DAM}mkv" -o -name "*${DAM}mp4" -o -name "*${DAM}avi" -o -name "*${DAM}m4v" -o -name "*${DAM}srt" exit 0; }; [[ $1 == -del ]] && { DELETE=true; shift 1; continue; }; echo "Parameter $1 discarded" usage exit done } usage() { printf "Usage: -r \tSearch/Replace Phrase -conf\t\tConfirm before moving -dry\t\tOnly perform a Dry Run -files\t\tRename Files in Parh(.) -file \tRename single File -dir\t\tRename Directories -path \tDefine Searchdirectory(Default .) -repair\t\tRepair broken Filenames -del\t\tDelete Garbage Torrent add files -l\t\tList Files -help\t\tDisplay this\n" } capitalize() { if [[ "$GOTO_PATH" == "true" ]]; then dir="${PWD##*/}" parent="${PWD%/*}" fi echo $dir echo "Capitalze Files" IFS=$'\n'; set -f FILE_ARR=() if [ "$1" == "" ]; then IFS=$'\n'; set -f for cont in ${container[@]}; do FILE_ARR=("${FILE_ARR[@]}" $(find . -type f -name "*${cont}")) done else FILE_ARR=("$1") fi FILE_ARR+=("$dir") SEP='[ 0123456789/.,\-_:;#$&()]' for f in "${FILE_ARR[@]}"; do dir=$(dirname -- "$f") filename=$(basename -- "$f") # ---- function to capitalize a name ---- capitalize() { local name="$1" # lowercase name=$(echo "$name" | sed 's/[A-Z]/\L&/g') # capitalize first letter name=$(echo "$name" | sed -E 's/^([a-z])/\u\1/') # capitalize after separators name=$(echo "$name" | sed -E "s@(${SEP})([a-z])@\1\u\2@g") echo "$name" } # ---- process directories ---- new_dir="" IFS='/' read -ra parts <<< "$dir" # Preserve absolute paths if [[ "$dir" == /* ]]; then new_dir="/" fi for part in "${parts[@]}"; do # Skip empty parts and "." [[ -z "$part" || "$part" == "." ]] && continue cap_part=$(capitalize "$part") if [[ "$new_dir" == "" || "$new_dir" == "/" ]]; then new_dir="${new_dir}${cap_part}" else new_dir="$new_dir/$cap_part" fi done # ---- process filename ---- if [[ "$filename" == *.* ]]; then base="${filename%.*}" ext="${filename##*.}" new_base=$(capitalize "$base") new_filename="$new_base.$ext" else new_filename=$(capitalize "$filename") fi # ---- build paths ---- old_path="${f#./}" new_path="$new_dir/$new_filename" # ---- create directories if needed ---- mkdir -p -- "$new_dir" # ---- move if different ---- if [[ "$old_path" != "$new_path" ]]; then echo "$old_path -> $new_path" if [[ "$old_path" == "${PWD##*/}" ]]; then mv -- "../$old_path" "../$new_path" cd "../$new_path" else mv -- "$old_path" "$new_path" fi fi done } repair_damage() { IFS=$'\n'; set -f for DAM in ${DAMAGE[@]}; do echo "Damage: ${DAM}" for file_orig in $(find . -name "*${DAM}mkv" -o -name "*${DAM}mp4" -o -name "*${DAM}avi" -o -name "*${DAM}m4v" -o -name "*${DAM}srt"); do file_path=$(echo ${file_orig} | rev | cut -f2- -d'/' | rev) file="$(echo $file_orig | rev | cut -f1 -d'/' | rev | sed 's/'"${DAM}"'srt/.srt/g' | sed 's/'"${DAM}"'avi/.avi/g'| sed 's/'"${DAM}"'mkv/.mkv/g' | sed 's/'"${DAM}"'mp4/.mp4/g')" echo "${file_orig} ${file_path}/${file}" mv "${file_orig}" "${file_path}/${file}" done done DAM=(" " "\.\." "__" "\[pseudo\]\.") COR=(" " "\." "_" "") for ((i = 0 ; i < ${#DAM[@]} ; i++)); do echo "Damage: ${DAM[$i]}" for file_orig in $(find . -name "*.mkv" -o -name "*.mp4" -o -name "*.avi" -o -name "*.m4v" -o -name "*.srt" | grep "${DAM[$i]}"); do file_path=$(echo ${file_orig} | rev | cut -f2- -d'/' | rev) file="$(echo ${file_orig} | rev | cut -f1 -d'/' | rev | sed 's/'"${DAM[$i]}"'/'"${COR[$i]}"'/g')" echo "${file_orig} ${file_path}/${file}" mv "${file_orig}" "${file_path}/${file}" done done for ((i = 0 ; i < ${#DAM[@]} ; i++)); do echo "Damage: ${DAM[$i]}" for file_orig in $(find . -type d | grep "${DAM[$i]}"); do file_path=$(echo ${file_orig} | rev | cut -f2- -d'/' | rev) file="$(echo ${file_orig} | rev | cut -f1 -d'/' | rev | sed 's/'"${DAM[$i]}"'/'"${COR[$i]}"'/g')" if [ "$(find ${file_path}/${file} -name *mkv -o -name *mp4 -o -name *avi)" == "" ]; then echo "${file_path}/${file} is no Media Directory" continue fi echo "${file_orig} ${file_path}/${file}" mv "${file_orig}" "${file_path}/${file}" done done unset IFS; set +f } rename_files() { echo "Rename Files" IFS=$'\n'; set -f FILE_ARR=() if [ "$1" == "" ]; then IFS=$'\n'; set -f for cont in ${container[@]}; do FILE_ARR=("${FILE_ARR[@]}" $(find . -type f -name "*${cont}")) done else FILE_ARR=("$1") fi # echo ${FILE_ARR[*]} # echo "Rename?" # if [ "$ans" != "y" ]; then # exit # fi i=0 for file_orig in ${FILE_ARR[@]}; do file=$(echo ${file_orig} | rev | cut -f1 -d'/' | rev) file="$(echo "$file" | sed 's/ /./g')" file="$(echo "$file" | sed 's/s\([0-9]\{2\}\)e/S\1E/g')" file_path=$(echo ${file_orig} | rev | cut -f2- -d'/' | rev) for cont in ${container[@]}; do for part in ${unwanted_filename_parts[@]}; do file_new="$(echo "$file" | sed "s/${part}.*\.${cont}/\.${cont}/g")" if [ ${#file_new} -gt 10 ]; then file=${file_new} else echo "Filename without unwanted part too short: $file, $part" file_new="$(echo "$file" | sed "s/${part}//g")" if [ ${#file_new} -gt 10 ]; then file=${file_new} else echo "Filename without unwanted part too short: $file, $part" fi fi done done if [ "${file:0:1}" == '.' ]; then file=${file:1:${#file}} fi if [ "${SR}" == "true" ] && [ "${search}" != "" ] && [ "${replace}" != "" ]; then file="$(echo "$file" | sed "s/${search}/${replace}/g")" fi if [ "${file_orig}" != "${file_path}/${file}" ]; then if [ "${DRY_RUN}" == "false" ]; then echo "${file_orig} ${file_path}/${file}" if [ "${CONFIRM}" == "true" ]; then read fi mv -i "${file_orig}" "${file_path}/${file}" else echo "Dry rename ${file_orig} ${file_path}/${file}" fi fi ((i++)) STR="$i/${#FILE_ARR[@]}" printf "%s" "${STR}" echo -en "\033[${#STR}D" done unset IFS; set +f } rename_directories() { echo "Rename Directories" IFS=$'\n'; set -f if [ "$1" == "" ]; then FILE_ARR=($(find . -type d)) else FILE_ARR=($(find "$1" -type d)) fi i=0 if [[ "$GOTO_PATH" == "true" ]]; then dir="${PWD/}" FILE_ARR+=("$dir") fi #echo "Rename?" #read -n 10 ans #if [ "$ans" != "y" ]; then # exit #fi for file_orig in ${FILE_ARR[*]}; do if [ "${file_orig}" == '.' ]; then continue fi echo ${file_orig} file="$(echo ${file_orig} | rev | cut -f1 -d'/' | rev)" file="$(echo "$file" | sed 's/\./ /g')" file_path=$(echo ${file_orig} | rev | cut -f2- -d'/' | rev) for part in ${unwanted_filename_parts[@]}; do file="$(echo "$file" | sed "s/${part}//g")" done if [ "${SR}" == "true" ] && [ "${search}" != "" ] && [ "${replace}" != "" ]; then file="$(echo "$file" | sed "s/${search}/${replace}/g")" fi if [[ "${file:${#file}-1:1}" == " " ]] || [[ "${file:${#file}-1:1}" == '.' ]]; then file="${file:0:${#file}-1}" fi if [ "${file:0:1}" == ' ' ]; then file=${file:1:${#file}} fi if [ "${file_orig}" != "${file_path}/${file}" ]; then if [ "${DRY_RUN}" == "false" ]; then echo "${file_orig} ${file_path}/${file}" if [ "${CONFIRM}" == "true" ]; then read fi mv "${file_orig}" "${file_path}/${file}" if [[ "${file_orig}" == "${PWD}" ]]; then cd "${file_path}/${file}" fi else echo "${file_orig} ${file_path}/${file}" fi fi ((i++)) STR="$i/${#FILE_ARR[@]}" printf "%s" "${STR}" echo -en "\033[${#STR}D" done unset IFS; set +f } delete_shit() { IFS=$'\n'; set -f for shit in ${KNOWN_SHIT_FILES[@]}; do printf "Shit: %s\n" "${shit}" find . -name "${shit}" find . -name "${shit}" -exec rm {} \; done } if [ $# -lt 1 ]; then echo "At least 1 Argument needed" usage exit fi get_config "$@" if [ "${GOTO_PATH}" == "true" ]; then cd "${GOTO}" fi if [ "${DIR_ONLY}" == "true" ]; then rename_directories "${GOTO}" fi printf "\n" if [ "${FILES_ONLY}" == "true" ]; then rename_files "${FILE}" fi printf "\n" if [ "${REPAIR_ONLY}" == "true" ]; then repair_damage fi if [ "${CAPITALIZE}" == "true" ]; then capitalize fi if [ "${DELETE}" == "true" ]; then delete_shit fi