RENAME - BULK FILE OPERATIONS
The Power of rename
The Perl rename command transforms filenames using regex. One command can rename hundreds of files following a pattern.
Syntax:
rename [options] 's/PATTERN/REPLACEMENT/' files
Safety First - Dry Run
ALWAYS test with -n (dry run) first:
rename -n 's/old/new/' *.txt
This shows what WOULD happen without actually renaming anything. Only remove -n when you're sure it's right.
Basic Replacements
Replace text in filenames:
rename 's/photo/image/' *.jpg
Before: photo_001.jpg, photo_002.jpg
After: image_001.jpg, image_002.jpg
The s/OLD/NEW/ syntax is Perl's substitution operator.
Case Conversion
Lowercase all filenames:
rename 'y/A-Z/a-z/' *
Uppercase all filenames:
rename 'y/a-z/A-Z/' *
The y/// is Perl's transliteration operator (character-by-character).
Removing Characters
Delete unwanted parts:
rename 's/_backup//' *.txt
Before: report_backup.txt
After: report.txt
Remove spaces:
rename 's/ //g' *
The g flag means "global" - replace ALL occurrences, not just the first.
Replacing Spaces
Spaces in filenames are annoying. Replace with underscores:
rename 's/ /_/g' *
Before: file with spaces.txt
After: file_with_spaces.txt
Or with dashes:
rename 's/ /-/g' *
Changing Extensions
Rename .jpeg to .jpg:
rename 's/\.jpeg$/.jpg/' *.jpeg
Important: escape the dot (\.) and anchor to end ($).
Without the anchor, "my.jpeg.photo.jpeg" would become "my.jpg.photo.jpeg" after the first replacement.
Batch change extensions:
rename 's/\.txt$/.md/' *.txt # txt to markdown
rename 's/\.htm$/.html/' *.htm # normalize HTML extension
Adding Prefixes
Add a prefix to all files:
rename 's/^/prefix_/' *
Before: file.txt
After: prefix_file.txt
The ^ means start of filename.
Adding Suffixes (Before Extension)
This is trickier. You need to insert before the extension:
rename 's/(\.\w+)$/_backup$1/' *
Before: report.txt
After: report_backup.txt
We'll explain capture groups in the next section.
Removing Prefixes
Remove IMG_ prefix from camera files:
rename 's/^IMG_//' IMG_*
Before: IMG_2024_06_15.png
After: 2024_06_15.png
Numbering Files
Sequential numbering is a bit more complex:
# First, let's use a counter
rename 's/^/sprintf("%03d_", ++$::count)/e' *
The /e flag evaluates Perl code in the replacement.
Before: apple.txt, banana.txt, cherry.txt
After: 001_apple.txt, 002_banana.txt, 003_cherry.txt
The Global Flag
Without g, only the first match is replaced:
rename 's/_/-/' a_b_c.txt
Result: a-b_c.txt
With g, all matches are replaced:
rename 's/_/-/g' a_b_c.txt
Result: a-b-c.txt
Use g when you want to replace every occurrence.
The Case-Insensitive Flag
Match regardless of case:
rename 's/PHOTO/image/i' *
This matches PHOTO, Photo, photo, pHoTo, etc.
Quick Examples
Normalize camera files:
rename 's/^DSC_?/photo_/' DSC*
Clean up AI-generated filenames:
rename 's/^\d{13}_//' *.png # Remove timestamp prefix
Add dates to files:
rename 's/^/2024-01-15_/' *.txt
Remove common junk:
rename 's/\s*\(copy\)//i' * # Remove "(copy)"
rename 's/\s*-\s*Copy//i' * # Remove "- Copy"
rename 's/_\d+(?=\.\w+$)//' * # Remove trailing numbers
Pro Tips
1. Always use -n first. Always.
2. Test on a copy of your files if you're nervous.
3. Use single quotes around the pattern to prevent shell expansion.
4. If a pattern doesn't match, the file isn't renamed (no error).
5. Process files in stages. Simple patterns, one step at a time.