DEV Community

Cover image for I Built a Zero-Dependency Python CLI to Batch Rename Files — Here's How It Works
Aayush Goswami
Aayush Goswami

Posted on

I Built a Zero-Dependency Python CLI to Batch Rename Files — Here's How It Works

rnmtool demo## The problem I was tired of ignoring

It was a Saturday afternoon. I had a folder of 80 files that looked like this:

01 Project Notes.txt
02 Sales Data 2024.csv
03 AppConfig.JSON
04 helper SCRIPT.py
...
Enter fullscreen mode Exit fullscreen mode

I needed them to look like this:

2025_01_project_notes.txt
2025_02_sales_data_2024.csv
2025_03_appconfig.json
2025_04_helper_script.py
...
Enter fullscreen mode Exit fullscreen mode

My options:

  • Rename them manually — 80 files × 30 seconds = 40 minutes of mind-numbing clicking
  • Write a one-off Python script — 20 minutes to write, works once, forgotten forever
  • Use a GUI bulk renamer — install something, learn its interface, probably overkill

None of these felt right. I wanted something I could type in any terminal, from any folder, in one line — and never think about again.

So I built rnmtool.


What is rnmtool?

rnmtool is a command-line file renaming utility written in Python. It lets you batch rename files using a combination of:

  • Find & replace (plain text or regex)
  • Case conversion (lower, upper, title)
  • Prefix / suffix injection
  • Extension swapping
  • Glob pattern filtering (only affect .txt files, for example)
  • Recursive directory renaming

And most importantly: a --dry-run mode that shows you exactly what will change before you commit to anything.

Zero external dependencies. Pure Python stdlib. Works on Windows, macOS, and Linux.


Installing it

pipx install rnmtool
Enter fullscreen mode Exit fullscreen mode

Don't have pipx? pip install pipx first.

After that, rnmtool is available globally — from any folder, any terminal session.

rnmtool --help
Enter fullscreen mode Exit fullscreen mode

Let's walk through real examples

The golden rule: always dry-run first

rnmtool my_folder --dry-run --find " " --replace "_"
Enter fullscreen mode Exit fullscreen mode

Output:

[rnmtool] DRY RUN — no files will be changed.

  BEFORE                        AFTER
  ────────────────────────────  ────────────────────────────────
  01 Project Notes.txt          01_Project_Notes.txt          ✓
  02 Sales Data 2024.csv        02_Sales_Data_2024.csv        ✓
  03 AppConfig.JSON             03_AppConfig.JSON             ✓
Enter fullscreen mode Exit fullscreen mode

Only after you're satisfied, drop --dry-run to apply.


Replace spaces with underscores

rnmtool my_folder --find " " --replace "_"
Enter fullscreen mode Exit fullscreen mode

Convert all filenames to lowercase

rnmtool my_folder --case lower
Enter fullscreen mode Exit fullscreen mode
03 AppConfig.JSON   →   03 appconfig.json
04 helper SCRIPT.py →   04 helper script.py
Enter fullscreen mode Exit fullscreen mode

Add a date prefix to every file

rnmtool my_folder --prefix "2025_"
Enter fullscreen mode Exit fullscreen mode
01 Project Notes.txt  →  2025_01 Project Notes.txt
02 Sales Data.csv     →  2025_02 Sales Data.csv
Enter fullscreen mode Exit fullscreen mode

Fix inconsistent file extensions

rnmtool my_folder --pattern "*.JSON" --ext .json
Enter fullscreen mode Exit fullscreen mode
03 AppConfig.JSON  →  03 AppConfig.json
Enter fullscreen mode Exit fullscreen mode

Strip leading numbers using regex

rnmtool my_folder --regex --find "^\d+\s"
Enter fullscreen mode Exit fullscreen mode
01 Project Notes.txt   →  Project Notes.txt
02 Sales Data.csv      →  Sales Data.csv
Enter fullscreen mode Exit fullscreen mode

Stack multiple transformations in one command

This is where it gets powerful. The transformations apply in a fixed order:

find/replace → case → prefix/suffix → extension

rnmtool my_folder --find " " --replace "_" --case lower --prefix "2025_"
Enter fullscreen mode Exit fullscreen mode
01 Project Notes.txt     →  2025_01_project_notes.txt
02 Sales Data 2024.csv   →  2025_02_sales_data_2024.csv
04 helper SCRIPT.py      →  2025_04_helper_script.py
Enter fullscreen mode Exit fullscreen mode

That's the exact transformation I needed on that Saturday — in one command.


Run from inside the target folder (no directory argument needed)

cd /path/to/my/messy/folder
rnmtool --dry-run --case lower
Enter fullscreen mode Exit fullscreen mode

The directory argument defaults to . (current folder). So you can cd into any folder and just run rnmtool.


How it compares to existing tools

I know what you're thinking — tools like f2 exist. And they're great. f2 is feature-rich and supports EXIF/ID3 metadata renaming, undo operations, and more.

But rnmtool is aimed at a different use case:

rnmtool f2
Language Python Go
Install pipx install rnmtool Binary download
Dependencies Zero (stdlib only) Go runtime
Undo support ❌ (dry-run instead)
Metadata renaming (EXIF/ID3)
Everyday file renaming
--dry-run preview

If you're already in a Python environment and want something you can install and forget — rnmtool is for you. If you need EXIF/ID3-based renaming for media files, use f2.


How it's built

The tool is ~200 lines of pure Python using only the standard library:

  • argparse — CLI interface
  • pathlib — file system operations
  • re — regex support
  • os — extension splitting

The src layout looks like this:

src/
└── rnmtool/
    ├── __init__.py
    └── __main__.py   ← everything lives here
Enter fullscreen mode Exit fullscreen mode

The core logic is split into three clean functions:

collect_files()         # glob matching + recursive search
apply_transformations() # all rename logic in one pipeline
run()                   # orchestrates dry-run vs. real run
Enter fullscreen mode Exit fullscreen mode

The transformation pipeline is intentional — by fixing the order (find/replace → case → prefix/suffix → extension), users get predictable, composable behavior without having to think about ordering themselves.


Included: a test folder to play with

The repo ships with a test_files/ folder containing 12 dummy files of varied types — .txt, .csv, .json, .py, .md, .html, .XML, .log, .yaml, .sql, .bat, .ini — specifically designed to let you safely experiment with every feature without touching real files.

# Clone the repo and try it immediately
git clone https://github.com/AayushGoswami/rnmtool.git
cd rnmtool
pip install -e .
rnmtool test_files --dry-run --case lower
Enter fullscreen mode Exit fullscreen mode

Try it

# Install
pipx install rnmtool

# Preview renaming every file in a folder
rnmtool /your/folder --dry-run --find " " --replace "_" --case lower

# Apply when satisfied
rnmtool /your/folder --find " " --replace "_" --case lower
Enter fullscreen mode Exit fullscreen mode

GitHub: AayushGoswami/rnmtool
PyPI: pypi.org/project/rnmtool


If you've ever spent more than 5 minutes manually renaming files, give it a try. And if you find a bug or have a feature idea, open an issue — contributions are very welcome.


Built with Python's standard library — zero dependencies required.

Top comments (0)