rename (util-linux)¶
rename replaces a fixed string in one or more file names. It's the quickest way to bulk-rename files without writing a loop.
Which
renamedo you have? There are two unrelated tools with the same name:
Variant Syntax Found on util-linux renamerename FROM TO FILES...(plain strings)RHEL, Fedora, Arch, Alpine; rename.ulon Debian/UbuntuPerl rename(prename,file-rename)rename 's/regex/repl/' FILES...Default renameon Debian/UbuntuCheck with
rename --version. util-linux printsrename from util-linux 2.x. This page covers the util-linux version.
Syntax¶
rename [options] <expression> <replacement> <file>...
expression— literal string to find (not a regex)replacement— string to put in its place (can be empty''to delete)file...— usually a shell glob
By default only the first occurrence in each name is replaced.
Options¶
| Option | Description |
|---|---|
-n, --no-act |
Dry run; show what would happen (pair with -v) |
-v, --verbose |
Print each rename performed |
-o, --no-overwrite |
Don't clobber existing files |
-i, --interactive |
Prompt before overwriting |
-a, --all |
Replace every occurrence, not just the first |
-l, --last |
Replace the last occurrence instead of the first |
-s, --symlink |
Rewrite the target of symlinks rather than the link names |
-aand-lwere added in util-linux 2.38; older systems (e.g. RHEL 8/9) won't have them.
Always dry-run first¶
rename -nv .jpeg .jpg *.jpeg
`photo1.jpeg' -> `photo1.jpg'
`photo2.jpeg' -> `photo2.jpg'
Drop -n once the output looks right.
Common examples¶
Change an extension
rename -v .jpeg .jpg *.jpeg
Strip a prefix
rename -v 'IMG_' '' IMG_*.jpg
Add a prefix (you can't match "nothing", so match a known leading string and include it in the replacement)
rename -v 'report' '2026-report' report*.pdf
Replace all spaces with underscores (needs -a)
rename -av ' ' '_' *
On older util-linux without -a, run it repeatedly until nothing changes:
while rename ' ' '_' *\ * 2>/dev/null; do :; done
Change only the last occurrence (handy for extensions on names with dots)
rename -lv '.bak' '' config.bak.bak
# config.bak.bak -> config.bak
Zero-pad numbered files (one pass per digit length)
rename -v 'file' 'file0' file?.txt # file1.txt -> file01.txt
Avoid clobbering existing files
rename -ov .log .txt *.log
Retarget symlinks after moving a directory
rename -sv /opt/app-old /opt/app-new /etc/alternatives/app*
Recursive rename (rename has no -r; combine with find)
find . -type f -name '*.jpeg' -exec rename -v .jpeg .jpg {} +
Directories renamed while find is walking them can break traversal — use -depth when renaming directory names:
find . -depth -name '*old*' -exec rename -v old new {} +
Exit status¶
| Code | Meaning |
|---|---|
0 |
All requested renames succeeded |
1 |
All renames failed |
2 |
Some renames failed |
4 |
Nothing was renamed (expression not found) |
64 |
Unanticipated error |
Useful in scripts — 4 tells you the pattern matched nothing.
Gotchas¶
- Not a regex.
rename '.*' ...looks for a literal.*. Use the Perlrenameor a shell loop for patterns. - Matches the whole path.
rename a b dir/a.txtchanges the firstaindir/a.txt— fine here, butrename d x data/d.txthits the directory part.cdinto the directory or make the expression specific. - Quote spaces and empty strings.
''for an empty replacement,' 'for a space. - Debian/Ubuntu: install
util-linux(already present) and callrename.ul, or install therenamepackage for the Perl variant.
Shell-only alternative¶
When rename isn't available or you need logic it can't express:
for f in *.jpeg; do mv -n -- "$f" "${f%.jpeg}.jpg"; done
See also¶
man 1 renamemmv,mv, Perlrename(file-rename)