This is a mess. How do I know which command to use when we expect Perl's rename with s///
sed-like syntax, when there're tons of different implementations of rename
, that are different versions of the Perl one or most of the time rename.ul
(binary)?

- 72,889

- 33,867
-
6Dropping a comment here so the two questions are linked: What's with all the renames: prename, rename, file-rename? – terdon Jan 07 '23 at 15:50
-
Linked together, here I go more in depth. Thanks for reporting – Gilles Quénot Jan 07 '23 at 22:00
1 Answers
Perl's rename
The most well-known and intuitive tool for bulk renaming files is Perl's rename
. It is pretty much like sed
on steroids (but meant for renaming files).
TL;DR
If you want to use it the expected way, better use Perl's CPAN to install the expected version. There's too many versions out there.
See "Generic Perl CPAN install" below.
Usage (sed
s///
like)
It's able to do powerful regex processing:
rename [options] 's/<regex>/<replacement>/[modifiers]' <FILE(S)>[*]
<STDIN> | rename [options] 's/<regex>/<replacement>/[modifiers]'
Examples
If you want to add spaces between each word of an mp4 filename in
TitleCase
(PascalCase
to Words Separated By Spaces):rename -n 's/\B[[:upper:]]/ $&/g' ./*.mp4 rename(./FooBarBaz.mp4, ./Foo Bar Baz.mp4)
Remove
-n
switch, akadry-run
when your attempts are satisfactory to rename for real.you even can inject calls in the
replacement
part, likesprintf "%03d", 7
zero padding with thee
modifier:$ touch {1..3}.txt $ rename -n 's/(\d+)\.txt/sprintf "%03d", $1/e' ./*.txt rename(1.txt, 001.txt) rename(2.txt, 002.txt) rename(3.txt, 003.txt)
reverse order of text separated by
-
using capture group:$ rename -n 's/(\w+)-(\w+)-(\w+)/$3-$2-$1/' ./foo-bar-base.txt rename(foo-bar-base.txt, base-bar-foo.txt)
or using
Perl
ish way (TMTOWTDI):$ rename -n 's/(\w+)-(\w+)-(\w+) # capture groups /join "-", reverse @{^CAPTURE}/xe' foo-bar-base.txt rename(foo-bar-base.txt, base-bar-foo.txt)
You (Wo|Do)n’t Learn Perl in Five Minutes
Getting to grips with Perl is time well spent. But to start using the time-saving capabilities of the rename command, you don’t need to have much Perl knowledge at all to reap large benefits in power, simplicity and time.
Check your own version
There's another binary tool with the same name used on some distro. Depending on your distro, the Perl version can be called
perl-rename
, file-rename
, prename
, pname
or rename
.
There's also a Python rename
command out there !
rename --version
should look like this:
/usr/bin/rename using File::Rename version 1.30, File::Rename::Options version 1.10
or on old versions:
Unknown option: help
Usage: rename [-v] [-n] [-f] perlexpr [filenames
Or
rename 2>&1 | grep -i perl
[ -e|-E perlexpr]*|perlexpr [ files ]
And not something using rename
from util-linux
Table of default versions VS distros of rename command
Borrowed from this comment on tldr-pages's GitHub issue tracker by @mebeim:
Perl (old) Perl (new) Perl (other?) C Linux (Debian) prename (pkg perl), deprecated file‑rename (pkg rename) N/A rename.ul (pkg util-linux) Linux (Ubuntu) N/A file‑rename (pkg rename) N/A rename.ul (pkg util-linux) Linux (Arch) N/A N/A perl‑rename (pkg perl-rename) rename (pkg util-linux) Linux (CentOS, RHEL) N/A N/A N/A rename (pkg util-linux) Linux (Fedora) N/A N/A prename (pkg prename) rename (pkg util-linux) Linux (openSUSE) N/A N/A N/A rename (pkg util-linux) macOS (Homebrew) N/A N/A rename (pkg rename) rename (pkg util-linux) Windows N/A N/A N/A N/A Solaris N/A N/A N/A N/A
Important notes:
on Windows,
rename
is a completely different command (therefore I did not list it above), but can be used as well, check how to use Perl's rename on windowson Solaris, no
rename
command existson macOS, the Homebrew packages
rename
andutil-linux
conflicton macOS, the Homebrew package
rename
offers a Perl script that looks different from the otherson Arch Linux, the
perl-rename
package offers a Perl script that's also different from the otherson Feroda, the
prename
offers a Perl script that's also different from the otherson Debian,
prename
andfile-rename
are alternatives forrename
on Ubuntu,
file-rename
is the only alternative forrename
mksh has a builtin
rename
. To use Perl'srename
, it is necessary to either use full path:/usr/bin/rename
, or define analias rename=/usr/bin/rename
Generic Perl CPAN
install with or without root privileges
I recommend this way, since there're too many different versions around. This way, you know exactly which version you will have.
- use
cpan -i File::Rename
(Better use perl brew for regular user). Therename
command will be available. If not, yourPATH
does not include Perl script utilities. - for
Debian*
, usedh-make-perl --build --cpan File::Rename
to make a Debian package
If you can't install anything, download it as a standalone script (simplified old version with no dependencies (except perl
) and less switches than the newer versions)
Mapping rename
VS distros if not the good one
If you prefer your system package manager:
This is the default rename
command on Debian (alternative) like OS (unlike Arch Linux, rpm
-based distros, Slackware and *BSD).
rpm
-based distros:dnf install prename
Arch Linux/Manjaro:
pacman -S perl-rename
Gentoo:
emerge dev-perl/rename
NixOs:
nix-env -i perl5.36.0-rename nix-env -iA nixos.perlRename
This is not the recommended way for purists.
*BSD:
pkg install p5-File-Rename
Alpine Linux (in branch
edge
of thetesting
repository, not used by default):apk add perl-file-rename --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/
macOS:
brew install rename
Debian-like/Ubuntu:
apt install rename
Slackware:
slackbuild
Documentation
- check perl's doc about rename
- perldoc perle#character classes is a must read page to understand the shorts
\d
,\w
\s
... (PCRE, Perl, Python, PHP)
Unicode
There's also a specific Unicode rename
implementation: Unicode::Tussle
If you have file with contiguous Unicode UTF8 characters like AaaÃééZzz.mp4
the Unicode part will be ignored. One solution is to use the special switch for unicode
:
-u, --unicode [encoding]
Treat filenames as perl (unicode) strings when running the user-supplied code.
Decode/encode filenames using encoding, if present.
encoding is optional: if omitted, the next argument should be an option starting with '-', for instance -e.
or if you have a (older) version without -u
, you can do:
PERL_UNICODE=ASD rename -n 's/\B\p{Lu}/ $&/g' ./*.mp4
Check
perldoc perlrun | less +/PERL_UNICODE
Security
To avoid possible shell injection (thanks @Stephane Chazelas):
rename -n 's/.*//' '--e=system"uname"#.mp4'
Linux
Make it a habit to use: (the most portable)
rename -n 's/.*//' ./*
or if supported:
rename -n 's/.*//' -- *
It will both prevent shell injection and treating files starting with -
as a switch.
Try to rename a file like rename -n 's/.*//' -foobar.txt

- 781
- 1
- 4
- 12

- 33,867
-
1(Coming from https://unix.stackexchange.com/a/757503/367454). In Alpine Linux, there is a package
perl-file-rename
, but it is in thetesting
repository ofedge
branch and isn't installed by default. Furthermore, mksh hasrename
as a builtin. Quotingman mksh
: rename [--] from to (defer always, needs rename(2)) Renames the file from to to. Both pathnames must be on the same device. Intended for emergency situations (where /bin/mv becomes unusable); thin syscall wrapper. – Vilinkameni Sep 26 '23 at 21:27