Ubuntu – How to make a shell script to move files to individual folders based on the filename

bashscripts

I want to automate moving TV show episode files into individual directories for each episode.

Essentially, in the folder I want to run the script in, I have a list of files. For example: tvshow.2009.S01E01.episodename1.mkv,
tvshow.2009.S01E02.episodename2.mkv, tvshow.2009.S01E03.episodename3.mkv, ect.
and empty directories in the format E01, E02, E03, ect.

I have been moving the files manually at this point with the help of Tab autocompletion at the command line. Essentially I am typing:

mv t

and then hitting the Tab key to autocomplete out to

mv tv.show.2009.S01E0

then type 1 and Tab again to get to

mv tv.show.2009.S01E01.episodename1.mkv 

then I type the correct folder to get to

mv tv.show.2009.S01E01.episodename1.mkv E01/

and then hit Enter to complete the command. I have to repeat the steps for as many episodes as I have in the original directory, and given the fact I am essentially repeating the same steps and just iterating the episode number, it seems like a perfect use of a for loop in a script.

The issue is that the files are not always in the same format, and will obviously have different names depending on the show. What is constant though is that S##E## will always appear in the filename and I only need to use the E## to identify the correct file and move it into the folder that already exists and exactly matches the E## from the file.

I am an experienced programmer, but have not worked with shell scripts yet. My thought is to maybe iterate through all the existing E## folders, look for a file that contains that E## sequence, and then move that file into the folder. Unfortunately I am not sure the correct approach in doing this with a script that I can run on the command line.

Would anyone have a suggested plan of approach or be able to point me towards a resource I could refer to for help?

Best Answer

Here is the solution I came up with thanks to the other answers given

#!/bin/bash

for f in *.mkv *.mp4 *.wmv; do
        if [ -f "$f" ] # does file exist?
        then
                dir=$(echo "$f" | grep -o "E[0-9][0-9]" | head -1) # extract first E## from filename
                if [ "$dir" ] # check if string found
                then
                        mkdir -p "$dir"  # create dir
                        mv "$f" "$dir"     # move file into new dir
                else
                        echo "INCORRECT FILE FORMAT: \""$f"\"" # print error if file format is unexpected
                fi
        fi
done

I had to add some error checking to catch any files that are incorrectly formatted and for double episode files where the filename has two matching E## strings (for example tvshow.S01E20E21.mkv). For double episode files it will create a directory for the first episode number only and move the file to there. Note that this script will make the E## directories as well since it makes it easier to have one script do it all.

Related Question