| name | batch-renamer |
| description | Rename files in bulk using pattern-based rules, regex capture groups, numbering sequences, case conversions, and date-based renaming. Use when renaming multiple files at once, adding prefixes/suffixes, numbering files, or organizing files by date. Triggers include "rename files", "bulk rename", "add prefix to files", "number files", "rename with pattern", "ren command". |
batch-renamer
CLI tool for bulk file renaming with preview, undo, and conflict detection.
Quick Start
ren "*.jpg" "{date}_{name}{ext}" --dry-run
ren "*.jpg" "{date}_{name}{ext}"
ren "*.jpg" "{date}_{name}{ext}" --yes
ren undo
Pattern Variables
| Variable | Description | Example Input | Example Output |
|---|
{name} | Filename without extension | photo.jpg | photo |
{ext} | Extension with dot | photo.jpg | .jpg |
{index} | 1-based sequence number | file 3 of 25 | 3 |
{index:3} | Zero-padded to N digits | file 3 of 25 | 003 |
{date} | Today YYYY-MM-DD | any | 2026-03-20 |
{year} | Current year | any | 2026 |
{month} | Current month MM | any | 03 |
{day} | Current day DD | any | 20 |
{dir} | Parent directory name | /photos/beach/img.jpg | beach |
{1}, {2} | Regex capture groups | see --regex | group value |
Common Patterns
ren "*.jpg" "{date}_{name}{ext}"
ren "*.mp3" "{index:3}_{name}{ext}"
ren "*.png" "{name}_backup{ext}"
ren "*.jpg" "{year}/{name}{ext}"
ren "*.jpg" "{date}_{index:4}_{name}{ext}"
Regex Mode
ren --regex "^IMG_(\d+)" "photo_{1}" "*.jpg"
ren --regex "^(\d{4})-(\d{2})-(\d{2})_(.*)" "{1}{2}{3}_{4}" "*.jpg"
ren --regex "(?<year>\d{4})-(?<month>\d{2})" "{year}_{month}" "*.log"
Case Conversion
ren --uppercase "*.txt"
ren --lowercase "*.TXT"
ren --titlecase "*.txt"
ren --kebab "*.txt"
ren --snake "*.txt"
Date-Based Renaming
ren --date-prefix "*.jpg"
ren --date-exif "*.jpg" "{date}_{name}{ext}"
Recursive Mode
ren --recursive "**/*.txt" "{name}.bak"
ren --recursive "**/*.js" "{name}.mjs" --ignore node_modules --ignore dist
Batch Mode
ren batch operations.json
ren batch operations.json --continue-on-conflict
operations.json format:
[
{ "glob": "*.jpg", "pattern": "{date}_{name}{ext}" },
{ "glob": "*.png", "pattern": "{date}_{name}{ext}" }
]
Undo
ren undo
ren stats
CLI Reference
| Flag | Description |
|---|
--dry-run | Preview only, no file changes |
--yes | Apply without confirmation prompt |
--recursive | Walk subdirectories |
--ignore <pattern> | Exclude matching paths (repeatable) |
--regex <from> <to> | Regex mode with capture groups |
--uppercase | Convert to uppercase |
--lowercase | Convert to lowercase |
--titlecase | Convert to title case |
--kebab | Convert to kebab-case |
--snake | Convert to snake_case |
--date-prefix | Prepend current date |
--date-exif | Use EXIF date from JPEG |
--force | Apply even with conflicts |
--skip-conflicts | Skip conflicting files, rename rest |
--continue-on-conflict | Batch mode: continue after conflicts |
--no-color | Disable ANSI color output |
--version | Show version |
--help | Show help |
Environment Variables
| Variable | Default | Description |
|---|
BREN_UNDO_PATH | ~/.local/share/batch-renamer/undo.json | Path to undo stack file |
BREN_NO_COLOR | 0 | Disable ANSI color (1 to disable) |
BREN_DRY_RUN | 0 | Always run in dry-run mode (1 to enable) |
BREN_DEBUG | 0 | Enable debug logging (1 to enable) |
Exit Codes
| Code | Meaning |
|---|
| 0 | Success |
| 1 | No files matched the glob pattern |
| 2 | Conflicts detected and not resolved |
| 3 | Runtime error |
Troubleshooting
No files matched - Check that your glob pattern is quoted to prevent shell expansion. Use --dry-run to test patterns safely.
Conflict: destination already exists - Use --skip-conflicts to skip those files, or --force to overwrite.
Undo stack is empty - No previous rename operations to undo in the current session.
EXIF date not found - Install exiftool and ensure the JPEG file has DateTimeOriginal or CreateDate metadata.