Bulk Rename Files in Python with Regex Replacement
Renames every file in a directory by applying a regex substitution to its filename using Python's stdlib re and pathlib.
Python code
29 linesimport re
from pathlib import Path
def bulk_rename_regex(directory, pattern, replacement):
path = Path(directory)
renamed = []
for file in path.iterdir():
if file.is_file():
new_name = re.sub(pattern, replacement, file.name)
if new_name != file.name:
new_path = file.with_name(new_name)
file.rename(new_path)
renamed.append((file.name, new_name))
return renamed
if __name__ == "__main__":
import tempfile
import os
with tempfile.TemporaryDirectory() as tmpdir:
for name in ["file1.txt", "file2.txt", "photo1.jpg", "photo2.jpg"]:
Path(tmpdir, name).touch()
result = bulk_rename_regex(tmpdir, r"\d+", "X")
for old, new in result:
print(f"{old} -> {new}")
print("---")
print(sorted(f.name for f in Path(tmpdir).iterdir()))
Output
file1.txt -> fileX.txt
file2.txt -> fileX.txt
photo1.jpg -> photoX.jpg
photo2.jpg -> photoX.jpg
---
['fileX.txt', 'photoX.jpg']
How it works
The function iterates over all entries in the given directory using Path.iterdir(), filtering only regular files with is_file() to avoid renaming folders. For each file, re.sub() applies the regex pattern to the filename only (not the full path) and returns a possibly new name. If the new name differs, it constructs a new Path with with_name() and calls rename() to perform the filesystem operation. The list of old and new names is collected and returned, so callers can log or verify what was renamed after the loop finishes. Because the script uses temporary files, the output shows exactly which files matched the digit pattern and what they became, plus the final directory listing.
Common mistakes
- Calling `rename()` on a Path that still points to the old location—you must use `with_name()` or `parent / new_name`.
- Using a pattern that also matches the directory path when applying `re.sub` to the full `str(file)` instead of `file.name`.
- Forgetting to check `is_file()` so directories or symlinks get renamed accidentally.
- Not collecting results before printing, so the `rename()` call may overwrite existing files silently.
Variations
- Use `path.glob('*')` instead of `iterdir()` if you only want files matching a given wildcard pattern.
- Add a dry-run mode that prints proposed renames without actually renaming, by skipping `file.rename(new_path)`.
Real-world use cases
- Normalizing exported files from a camera or download folder to replace timestamps like IMG_20230101 with readable labels.
- Cleaning up log files by removing date stamps or trailing version numbers so backups are consistent.
- Migrating a codebase's asset names by stripping spaces and special characters into snake_case for CI pipelines.
Sponsored
More from Automation & scripting
- Aggregate Log Errors Count by Hour in Python easy
- Automate Tweeting New Blog Posts in Python easy
- Automatically Clean Temporary Files from Applications Using Python medium
- Automatically Download the Latest Software Release from GitHub with Python medium
- Automatically Generate Charts from CSV Files with One Command medium
- Automatically Generate Hardware Inventory Reports in Python easy
Keep learning
Related tutorials and quizzes for this topic.