## 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
...
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
...
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
.txtfiles, 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
Don't have pipx?
pip install pipxfirst.
After that, rnmtool is available globally — from any folder, any terminal session.
rnmtool --help
Let's walk through real examples
The golden rule: always dry-run first
rnmtool my_folder --dry-run --find " " --replace "_"
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 ✓
Only after you're satisfied, drop --dry-run to apply.
Replace spaces with underscores
rnmtool my_folder --find " " --replace "_"
Convert all filenames to lowercase
rnmtool my_folder --case lower
03 AppConfig.JSON → 03 appconfig.json
04 helper SCRIPT.py → 04 helper script.py
Add a date prefix to every file
rnmtool my_folder --prefix "2025_"
01 Project Notes.txt → 2025_01 Project Notes.txt
02 Sales Data.csv → 2025_02 Sales Data.csv
Fix inconsistent file extensions
rnmtool my_folder --pattern "*.JSON" --ext .json
03 AppConfig.JSON → 03 AppConfig.json
Strip leading numbers using regex
rnmtool my_folder --regex --find "^\d+\s"
01 Project Notes.txt → Project Notes.txt
02 Sales Data.csv → Sales Data.csv
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_"
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
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
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
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
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
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
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)