Moving Files into Individual Folders with Bash

If you run a home media server using Jellyfin, Plex, or Emby, you know that organization is everything.

To get the best experience—specifically to ensure that “sidecar” files (like .srt subtitles, .nfo metadata files, and movie posters) are correctly detected—it is best practice to have each movie in its own dedicated folder.

For example:

  • The messy way: Movies/Inception.mp4
  • The organized way: Movies/Inception/Inception.mp4

If you have a massive folder full of loose video files, you don’t want to create these folders manually. In this post, I’ll show you a quick Bash one-liner to automate this process.

The Problem

You have a directory containing hundreds of movie files. You need to:

  1. Identify each file.
  2. Create a new folder named exactly like the file (minus the extension).
  3. Move the file into that new folder.

The Solution: The Bash Script

Here is a simple script to handle this.

Bash
for file in *; do
    if [[ -f "$file" ]]; then
        mkdir "${file%.*}"
        mv "$file" "${file%.*}"
    fi
done

How It Works: A Breakdown

If you aren’t a Bash expert, the syntax ${file%.*} might look a bit intimidating. Let’s break down what is happening under the hood:

  • for file in *; do: This starts a loop that looks at every single item in your current directory.
  • if [[ -f "$file" ]]; then: This is a safety check. It asks, “Is this actually a file?” This prevents the script from trying to move a folder into itself, which would cause errors.
  • mkdir "${file%.*}": This is the magic part.
    • ${file%.*} is a “shell parameter expansion.” It tells the script: “Take the filename, but strip everything from the last dot (.) to the end of the string.”
    • If the file is jellyfish.mp4, this command results in mkdir jellyfish.
  • mv "$file" "${file%.*}": This moves the original file into the newly created directory.
  • fi; done: This simply closes the if statement and the for loop.

Step-by-Step Guide to Using It

1. Test it first (The “Dry Run”)

Before running a command that moves files, always run a “dry run” to make sure it does exactly what you expect. Add echo before the commands to see what would happen without actually doing it:

Bash
for file in *; do
    if [[ -f "$file" ]]; then
        echo "Creating folder: ${file%.*}"
        echo "Moving $file to ${file%.*}"
    fi
done

2. Run the actual script

Once you are happy with the output, run the actual command in your terminal:

  1. Open your terminal.
  2. cd into your media directory: cd /path/to/your/movies
  3. Paste the script and hit Enter.

Pro-Tip: Handling Multiple Extensions

The script above works perfectly for most cases. However, if you have files with multiple extensions (like Movie.Name.1080p.x264.mp4), ${file%.*} only strips the last extension. For media management, this is exactly what you want!


Quick Summary for the Reader

CommandPurpose
mkdirCreates the new directory
${file%.*}Removes the file extension
[[ -f "$file" ]]Ensures we only touch files, not folders


Discover more from AddSpice

Subscribe to get the latest posts sent to your email.