Skip to content

Instantly share code, notes, and snippets.

@EldonMcGuinness
Last active November 10, 2024 02:53
Show Gist options
  • Save EldonMcGuinness/9720666d2ef9476908b23e33bad1f0af to your computer and use it in GitHub Desktop.
Save EldonMcGuinness/9720666d2ef9476908b23e33bad1f0af to your computer and use it in GitHub Desktop.
renameMovies
#!/bin/bash
#Version 1.20
# TODO: Handle multipart files .pt1.mkv .pt2.mkv etc
# Guess the Title
function guessTitle {
TEMP=$(echo $1 | sed 's/_/./g' | sed -E 's/\{.*?\}//g' | sed -E 's/\(\)//g' |sed -E 's/\(([0-9]{4})\)/\1/g' | sed -E 's/(.+)[0-9]{4}.*$/\1/' | sed -E 's/(.+)[0-9]{4}[^p].*$/\1/I' | sed -E 's/(.+)(1080|720|576|480)p.*$/\1/' | sed -E 's/(.+)[0-9]{4}$/\1/' | sed -E 's/([^\.]{2,})\./\1 /g' | sed -E 's/^([ai])\./\1 /gI' | sed -E 's/ ([ai0-9])\.([^0-9])/ \1 \2/gI' | sed -E 's/(([a-z0-9]\.)+)/\1 /gI' | sed -E 's/([0-9]+)\. ([0-9]+)/\1.\2/g' | sed -E 's/ / /' | sed -E 's/ $//' | sed -E 's/ $//' | sed -E 's/ ([0-9]+)\./ \1/')
if [ "$TEMP" != "$1" ]; then
echo "$TEMP"
else
echo $1 | sed 's/_/./g' | sed -E 's/\{.*?\}//g' | sed -E 's/\(([0-9]{4})\)/\1/g' | sed -E 's/(.+)[0-9]{4}.*$/\1/' | sed -E 's/(.+)[0-9]{4}[^p].*$/\1/I' | sed -E 's/(.+)(1080|720|576|480)p.*$/\1/' | sed -E 's/(.+)[0-9]{4}$/\1/' | sed -E 's/([^\.]{2,})\./\1 /g' | sed -E 's/^([ai])\./\1 /gI' | sed -E 's/ ([ai0-9])\.([^0-9])/ \1 \2/gI' | sed -E 's/(([a-z0-9]\.)+)/\1 /gI' | sed -E 's/([0-9]+)\. ([0-9]+)/\1.\2/g' | sed -E 's/ / /' | sed -E 's/ $//' | sed -E 's/ $//' | sed -E 's/ ([0-9]+)\./ \1/'
fi
}
# Guess the Year
function guessYear {
TEMP=$(echo $1 | sed -E 's/\(([0-9]{4})\)/\1/g' | sed -E 's/.+([0-9]{4})[^p].*$/\1/I' | sed -E 's/.+\(?([0-9]{4})\)?$/\1/')
if [ "$TEMP" == "$1" ]; then
echo ""
elif isYear $TEMP; then
echo "$TEMP"
else
echo ""
fi
}
# Guess the Edition
function guessEdition {
TEMP=$(echo $1 | sed -E 's/.*((limited|uncensored|imax|deluxe|criterion|collector|remastered|ultimate|international|german|dircut|uncut|director|alternate|theatrical|extended|unrated|final)).*/\1/gI')
TEMP=$(echo $TEMP | tr '[:upper:]' '[:lower:]')
if [ "$TEMP" == "$1" ]; then
echo ""
elif [ "$TEMP" != "" ]; then
case $TEMP in
limited) TEMP="Limited" ;;
uncensored) TEMP="Uncensored" ;;
imax) TEMP="IMAX" ;;
deluxe) TEMP="Deluxe" ;;
criterion) TEMP="Criterion" ;;
collector) TEMP="Collector's" ;;
ultimate) TEMP="Ultimate Cut" ;;
international) TEMP="International" ;;
german) TEMP="German Cut" ;;
dircut) TEMP="Director's Cut" ;;
uncut) TEMP="Uncut" ;;
director) TEMP="Director's Cut" ;;
alternate) TEMP="Alternate Cut" ;;
theatrical) TEMP="Theatrical Cut" ;;
extended) TEMP="Extended Edition" ;;
unrated) TEMP="Unrated Edition" ;;
final) TEMP="Final Cut" ;;
remastered) TEMP="Remastered" ;;
esac
if [ "$TEMP" == "$(echo $1 | tr '[:upper:]' '[:lower:]')" ]; then
TEMP=""
fi
echo $TEMP
else
echo ""
fi
}
# Check if we have a Year
function isYear {
re='^[0-9]{4}$'
if [[ $1 =~ $re ]]; then
return 0
else
return 1
fi
}
# Make the text pretty
function sPrint {
COLOR=0
STYLE=0
if [ "$2" != "" ]; then
case $2 in
black) COLOR=30 ;;
red) COLOR=31 ;;
green) COLOR=32 ;;
yellow) COLOR=33 ;;
blue) COLOR=34 ;;
magenta) COLOR=35 ;;
cyan) COLOR=36 ;;
white) COLOR=37 ;;
esac
fi
if [ "$3" != "" ]; then
case $3 in
normal) STYLE=0 ;;
bold) STYLE=1 ;;
dim) STYLE=2 ;;
inverse) STYLE=3 ;;
underline) STYLE=4 ;;
esac
fi
echo "\033[${STYLE};${COLOR}m${1}\033[0m"
}
# Print out the info to the terminal
function print {
TEXT="${*/!/\!}"
printf "$TEXT" > $(tty)
}
# Prompt the user with a binary question
function yesOrNo {
while true; do
read -p "$* "$'\e[1;36m[y/n]:\e[0m'" " -N 1 yn
case $yn in
[Yy]*) return 0 ;;
[Nn]*) return 1 ;;
*) return 0;;
esac
done
}
# Get a long form input from user
function getText {
GUESS_CHOICE=0
if [ "$2" != "" ]; then
read -p $'\e[32;1mUse '"$1"$' Guess\e[0m'" $2 "$'\e[1;36m[y/n]:\e[0m'" " -n 1 yn
case $yn in
[Nn]*) GUESS_CHOICE=1;;
esac
else
GUESS_CHOICE=1
fi
if [ $GUESS_CHOICE -eq 1 ]; then
print "\n"
read -p $'\e[31;1m'"$1"$'\e[0m'": " text
test=$(echo $test | sed -E 's/ $//')
print "\033[1A"
#print "\033[1A\033[2K"
else
echo "$2"
fi
echo "$text"
}
# Pretty print the directory contents
function listDirContents {
cd "$1"
for j in *; do
print "$(sPrint '|' 'yellow' 'bold')$j \n"
done
cd ..
}
# Set the default depth
DEPTH=0
# Look for files we want to work on
function searchForFiles {
# The default is to work on all the files in the current directory
SOURCE="*"
# If we are at the top level and were passed a file then work with it instead
if [ $DEPTH -eq 0 ]; then
if [ "$1" != "" ]; then
#print "Source Found: [$1] \n"
SOURCE=$1
fi
fi
# Loop through the files
for i in $SOURCE; do
#print "DEPTH: [$DEPTH]\n"
# If we are at the top level and the file to edit is the same as the source file
# we want to skip it
if [ $DEPTH -eq 0 ]; then
if [ "$i" == "$SOURCE" ]; then
continue;
fi
# Print the header
print "$(sPrint ' Movie Renamer ' 'white' 'inverse')\n"
# If this is a file then print it
if [ -f "$i" ]; then
print "$(sPrint '[File]' 'yellow' 'bold') $i\n"
# If this is a directory then print it and list the contents
elif [ -d "$i" ]; then
print "$(sPrint '[Directory]' 'yellow' 'bold') $i\n"
listDirContents "$i"
print "\n"
fi
fi
# If this is a directory
if [ -d "$i" ]; then
# Increment the depth to let us know we are working on something
DEPTH=$(($DEPTH+1))
#print "TITLE: [$TITLE]\n"
# If TITLE does not exist or is empty then try and guess the
# title and related info
if [ ! -v $TITLE ] || [ "$TITLE" == "" ]; then
#print "GUESSING...\n"
TITLE_GUESS=$(guessTitle "$i")
YEAR_GUESS=$(guessYear "$i")
EDITION_GUESS=$(guessEdition "$i")
# Build the guessed template
TEMPLATE_GUESS="$TITLE_GUESS"
if [ "$YEAR_GUESS" != "" ]; then
TEMPLATE_GUESS="$TEMPLATE_GUESS ($YEAR_GUESS)"
fi
if [ "$EDITION_GUESS" != "" ]; then
TEMPLATE_GUESS="$TEMPLATE_GUESS {edition-$EDITION_GUESS}"
fi
# Done building the guessed template
fi
#print "TG: [$TEMPLATE_GUESS]\n"
#print "D Comparing [$i] [$TEMPLATE_GUESS]\n"
# If the Guessed Title is different from the original file name then
# ask if we want to work on it
if [ "$i" != "$TEMPLATE_GUESS" ]; then
#print "Difference Detected: [$i] [$TEMPLATE_GUESS]\n"
if yesOrNo $'\e[34;1mWork on\e[0m'" $i?"; then
print "\n"
else
# If we don't want to work on it then decrement the depth
# and move to the next file
#read -p "STOP 1"
DEPTH=$(($DEPTH-1))
clear
continue
fi
# If we are here then we want to work on the file
# If TITLE does not exist or is empty then let the user
# enter the file info
#print "DEPTH: [$DEPTH]\n"
if ([ ! -v TITLE ] || [ "$TITLE" == "" ]) && [ $DEPTH -lt 2 ]; then
# Get the title
TITLE=$(getText "Movie Title" "$TITLE_GUESS")
print "\n"
# Get the year
YEAR=$(getText "Movie Year" "$YEAR_GUESS")
print "\n"
# Get the edition
EDITION=$(getText "Movie Edition" "$EDITION_GUESS")
print "\n"
# Build the user defined template
TEMPLATE="$TITLE"
if [ "$YEAR" != "" ]; then
TEMPLATE="$TEMPLATE ($YEAR)"
fi
if [ "$EDITION" != "" ]; then
TEMPLATE="$TEMPLATE {edition-$EDITION}"
fi
# Done building the user defined template
fi
#print "DEPTH: [$DEPTH]\n"
# Prompt the user if they want to move the file
if yesOrNo $'\e[34;1mMove\e[0m'" $i "$'\e[33;1m->\e[0m'" $TEMPLATE"; then
print "\n"
mv "$i" "$TEMPLATE" > /dev/null 2>&1
else
# If we don't want to move the file then decrement the depth
print "Skipping"
DEPTH=$(($DEPTH-1))
# If we are at the top level then clear the screen and move on
if [ $DEPTH -eq 0 ]; then
#read -p "STOP 2"
unset TITLE
clear
fi
continue
fi
else
# If the Guessed Title is the same as the original file name then
# set the template to the guessed title
TEMPLATE="$TEMPLATE_GUESS"
#DEPTH=$(($DEPTH-1))
#if [ $DEPTH -eq 0 ]; then
# read -p "STOP 3"
# unset TITLE
# clear
#fi
#continue
fi
# Move into the template directory and process the files
cd "$TEMPLATE"
searchForFiles
# Move back to the parent directory
cd ..
# Decrement the depth to show we are done working at this level
DEPTH=$(($DEPTH-1))
# If this is a file
elif [ -f "$i" ]; then
# Get the file extension
EXTENSION="${i##*.}"
# If we are at the top level and this is a file then work with it
if [ $DEPTH -eq 0 ]; then
TITLE_GUESS=$(guessTitle "$i")
YEAR_GUESS=$(guessYear "$i")
EDITION_GUESS=$(guessEdition "$i")
# Get the title
TITLE=$(getText "Movie Title" "$TITLE_GUESS")
print "\n"
# Get the year
YEAR=$(getText "Movie Year" "$YEAR_GUESS")
print "\n"
# Get the edition
EDITION=$(getText "Movie Edition" "$EDITION_GUESS")
print "\n"
# Build the user defined template
TEMPLATE="$TITLE"
if [ "$YEAR" != "" ]; then
TEMPLATE="$TEMPLATE ($YEAR)"
fi
if [ "$EDITION" != "" ]; then
TEMPLATE="$TEMPLATE {edition-$EDITION}"
fi
# Done building the user defined template
if yesOrNo $'\e[34;1mMove\e[0m'" $i "$'\e[33;1m->\e[0m'" $TEMPLATE.$EXTENSION"; then
print "\n"
mkdir "$TEMPLATE" > /dev/null 2>&1
mv "$i" "$TEMPLATE/$TEMPLATE.$EXTENSION" > /dev/null 2>&1
else
print "Skipping"
continue
fi
else
# If the file name is the same as the template name
if [ "$i" != "$TEMPLATE.$EXTENSION" ]; then
#print "Difference Detected: [$i] [$TEMPLATE.$EXTENSION]\n"
if [ ! -v TITLE ] && [ $DEPTH -eq 0 ]; then
TITLE=$(getText "Movie Title" "$TITLE_GUESS")
print "\n"
YEAR=$(getText "Movie Year" "$YEAR_GUESS")
print "\n"
EDITION=$(getText "Movie Edition" "$EDITION_GUESS")
print "\n"
TEMPLATE="$TITLE"
if [ "$EDITION" != "" ]; then
TEMPLATE="$TEMPLATE {edition-$EDITION}"
fi
if [ "$YEAR" != "" ]; then
TEMPLATE="$TEMPLATE ($YEAR)"
fi
fi
if yesOrNo $'\e[34;1mMove\e[0m'" $i "$'\e[33;1m->\e[0m'" $TEMPLATE.$EXTENSION"; then
print "\n"
mv "$i" "$TEMPLATE.$EXTENSION" > /dev/null 2>&1
else
print "Skipping"
continue
fi
else
print "Skipping"
continue
fi
fi
fi
if [ $DEPTH -eq 0 ]; then
#read -p "STOP 4"
unset TITLE
unset TEMPLATE
unset TEMPLATE_GUESS
clear
fi
done
}
clear
searchForFiles "$*"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment