This script creates one folder per file for every file of a given extension, and moves the file into it. Sidecar files that share the same name, for example a .srt or .nfo next to a .mkv, move into the same folder. It is useful for sorting a flat folder, for example a movie library with one file group per title.
For example, choosing .mkv turns Movie1.mkv and Movie1.srt into a folder named Movie1, containing both files.
Every real run writes a manifest of the moves it made, and that manifest can undo the run.
pip install -e .
mass-folder-creator --folder ./Movies --extension .mkvNo external dependencies are required. The package installs the script itself, plus the mass-folder-creator command.
Interactive mode, same as the original:
python FileToFolderMover.pyNon-interactive mode:
python FileToFolderMover.py --folder ./Movies --extension .mkv
python FileToFolderMover.py --folder ./Movies --extension .mkv,.mp4
python FileToFolderMover.py --folder ./Movies --extension .mkv --exclude "*.sample.*"
python FileToFolderMover.py --folder ./Movies --extension .mkv --min-age-days 1
python FileToFolderMover.py --folder ./Movies --extension .mkv --dry-run
python FileToFolderMover.py --folder ./Movies --extension .mkv --watch 3600 --yes
python FileToFolderMover.py --undo ./Movies/.mass-folder-creator-manifest-20260804-120000.json--extensionaccepts a comma-separated list, for example.mkv,.mp4,.avi.- The search is always recursive, into every subfolder.
--excludeskips a filename or path segment, matched as a glob pattern. It can be passed more than once.--min-age-daysonly organizes files last modified at least this many days ago, useful against a folder that is still downloading into.--follow-symlinksincludes symlinks. They are skipped by default.--forceallows a run against a folder the script flags as a system or home directory.--dry-runlists the files and sidecars that would move, without moving them.--yesskips the confirmation prompt, for scripted use.--watch SECONDSrepeats the run on an interval untilCtrl+C. It requires--yesor--dry-run, and cannot be combined with--undo.--verboseshows debug-level detail, including files skipped by--exclude,--min-age-days, or symlink filtering.--log-file PATHalso writes a timestamped record of the run to a file.--manifest PATHsets where the move manifest is written. By default it is a timestamped file inside the target folder.--undo MANIFEST_PATHreverses a previous run: it moves every file back to where it came from and removes the folders it created, if they are now empty.
The script refuses to run against a folder it resolves to a filesystem root, your home directory, or a known system directory name, unless --force is passed. Symlinks are skipped unless --follow-symlinks is set. Every real run writes a manifest before finishing, and that manifest is enough to reverse the run in full with --undo.
pip install -e ".[dev]"
pytestTests live in tests/ and cover file matching, sidecar grouping, the collision-suffix logic, the age and exclude filters, the dangerous-path guard, and a full organize-then-undo round trip. A GitHub Actions workflow (.github/workflows/tests.yml) runs the suite on Ubuntu, Windows, and macOS, on every push and pull request.