Bulk Image File Renaming - From OS Tools to Scripts
When Bulk Image Renaming Is Needed
Images from digital cameras and smartphones receive mechanical filenames like IMG_0001.jpg or DSC_1234.NEF. While a few files can be renamed manually, bulk renaming becomes essential when handling hundreds to thousands of images.
Typical scenarios requiring bulk renaming:
- Post-event organization: Renaming wedding, travel, or event photos by date and location
- E-commerce product images: Standardizing to product code + sequence (e.g.,
PROD-A001_01.jpg) - Website image assets: SEO-conscious filenames (e.g.,
tokyo-tower-night-view.jpg) - Multi-camera consolidation: Unifying images from different cameras into chronological sequence
- Backup/archive: Date-based filenames for long-term storage organization
Filename design principles:
- Use only alphanumeric characters, hyphens, and underscores (avoid spaces and non-ASCII)
- When including dates, use
YYYY-MM-DDformat at the beginning (natural sort order) - Ensure sufficient digit count for sequences (e.g., 0001-9999 not 001-999)
- Standardize extensions to lowercase (
.JPG→.jpg)
Renaming with OS Built-in Features
Here are OS-native renaming features available without additional software. Suitable for small to medium quantities (dozens of images).
macOS Finder:
- Select multiple files → Right-click → "Rename"
- Three modes: Replace Text / Add Text / Format (sequential numbering)
- "Format" mode generates custom name + sequence (e.g.,
vacation_001.jpg) - Starting number is configurable. Automatic date insertion is not available
Windows Explorer:
- Select multiple files → F2 key → Type new name → Enter
- Automatically assigns
New Name (1).jpg,New Name (2).jpgformat - Parenthesized numbering can be inconvenient for programmatic processing
Windows PowerRename (PowerToys):
- Advanced rename tool included in Microsoft's official PowerToys
- Supports regex search and replace
- Preview feature shows results before applying
- Example:
IMG_(\d+)→photo_$1convertsIMG_0001.jpgtophoto_0001.jpg
Limitations:
OS built-in features are convenient but cannot handle EXIF-based renaming (incorporating capture timestamps into filenames) or complex naming rules. Use command-line tools or scripts for those cases.
Command-Line Bulk Renaming
Command-line tools are ideal for applying complex naming rules and processing large file counts. They're reproducible and scriptable for repeated use.
rename command (Linux / macOS Homebrew):
- Install:
brew install rename(macOS) / pre-installed (most Linux distributions) - Basic syntax:
rename 's/pattern/replacement/' files - Example - lowercase extensions:
rename 's/\.JPG$/.jpg/' *.JPG - Example - add prefix:
rename 's/^/2026-03-/' *.jpg - Example - spaces to underscores:
rename 's/ /_/g' *.jpg -noption: Dry run (shows results without actual renaming)
ExifTool metadata-based renaming:
- Capture date as filename:
exiftool '-FileName<DateTimeOriginal' -d '%Y%m%d_%H%M%S%%-c.%%le' *.jpg - This renames
IMG_0001.jpgto something like20260215_143022.jpg %%-c: Sequential suffix for multiple shots in the same second%%le: Maintains original extension in lowercase- Include camera model:
exiftool '-FileName<${Model}_${DateTimeOriginal}' -d '%Y%m%d_%H%M%S%%-c.%%le' *.jpg
mmv (Mass Move and Rename):
- Pattern-matching bulk rename:
mmv 'IMG_*.jpg' 'photo_#1.jpg' #1references the portion matched by wildcard*
Safety measures:
Bulk renaming is difficult to undo, so always verify with a dry run (-n option) first, and create backups before executing when possible.
Advanced Renaming with Python Scripts
Python enables incorporating any custom logic including conditional branching, EXIF reading, and database integration into rename operations.
Basic sequential renaming:
import osfrom pathlib import Pathfolder = Path("./images")for i, file in enumerate(sorted(folder.glob("*.jpg")), start=1): new_name = f"photo_{i:04d}.jpg" file.rename(folder / new_name)
EXIF capture date-based renaming:
from PIL import Imagefrom PIL.ExifTags import TAGSfrom pathlib import Pathfrom datetime import datetimefolder = Path("./images")for file in folder.glob("*.jpg"): img = Image.open(file) exif = img._getexif() if exif and 36867 in exif: dt = datetime.strptime(exif[36867], "%Y:%m:%d %H:%M:%S") new_name = dt.strftime("%Y%m%d_%H%M%S") + file.suffix.lower() file.rename(folder / new_name)
Duplicate avoidance implementation:
To prevent filename collisions from multiple shots in the same second, incorporate duplicate checking with suffix addition logic:
def get_unique_name(folder, base_name, ext): candidate = folder / f"{base_name}{ext}" counter = 1 while candidate.exists(): candidate = folder / f"{base_name}_{counter:02d}{ext}" counter += 1 return candidate
Dry run mode implementation:
Always implement a dry run mode to verify changes before actual renaming. Switch with a --dry-run flag that only displays the before/after filename list. Make it a habit to always verify with dry run before production execution.
GUI Rename Tools
For users unfamiliar with command-line or who prefer visual preview while renaming, dedicated GUI rename tools are convenient.
macOS:
- A Better Finder Rename: The definitive macOS rename tool. Combines regex, EXIF info, sequences, dates, and more. Excellent preview feature
- NameChanger: Free simple rename tool. Supports search/replace, sequence addition, extension changes
Windows:
- Bulk Rename Utility: Feature-rich free Windows tool. Combines 14 rename operations including regex, sequences, dates, and EXIF. Complex UI but top-tier functionality
- Advanced Renamer: Intuitive UI for applying multiple rename methods sequentially. Batch list feature saves and reuses rename plans
Cross-platform:
- digiKam: Open-source photo management with built-in rename. Incorporates EXIF info (date, camera, lens) into filenames
- XnView MP: Image viewer and manager with batch rename functionality
GUI tool selection criteria:
- Preview feature: Can you verify results before applying?
- Undo feature: Can you revert incorrect renames?
- EXIF support: Can capture date and camera info be used in filenames?
- Regex support: Is complex pattern matching possible?
- Batch saving: Can rename rules be saved for reuse?
Trouble Prevention and Recovery Methods
Bulk renaming is convenient but incorrect operations can produce irreversible results. Establish prevention measures and recovery capabilities for emergencies.
Preventive measures:
- Always backup first: Copy the entire folder or use Git before renaming.
cp -r images/ images_backup/ - Execute dry runs: Preview results before actual renaming. ExifTool without
-execute, rename with-noption - Test on small samples: Test on a few copies before applying to all files
- Record rename logs: Save before/after filename mapping as CSV. Needed for recovery
Common troubles and solutions:
- Filename collisions: Existing same-named files get overwritten. Pre-check for duplicates and avoid with suffixes
- Extension loss: Regex mistakes delete extensions. Verify with dry run
- Character encoding issues: Japanese filenames cause encoding problems. Operate in UTF-8 environments
- Order disruption: Sort order differs from intent, causing sequence misalignment. Explicitly specify
sorted()keys
Recovery methods:
- With rename log (CSV): Apply reverse transformation via script
- Under Git management:
git checkout -- .to revert - With backup: Restore from backup
- None of the above: Can only estimate original filenames from EXIF capture dates (complete recovery is difficult)
Rename log recording example (Python):
import csvlog = []for old, new in renames: log.append({"old": old, "new": new})with open("rename_log.csv", "w") as f: writer = csv.DictWriter(f, fieldnames=["old", "new"]) writer.writeheader() writer.writerows(log)