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)?
- 6Dropping a comment here so the two questions are linked: What's with all the renames: prename, rename, file-rename?terdon– terdon ♦2023-01-07 15:50:22 +00:00Commented Jan 7, 2023 at 15:50
- Linked together, here I go more in depth. Thanks for reportingGilles Quénot– Gilles Quénot2023-01-07 22:00:15 +00:00Commented Jan 7, 2023 at 22:00
1 Answer
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(PascalCaseto Words Separated By Spaces):rename -n 's/\B[[:upper:]]/ $&/g' ./*.mp4 rename(./FooBarBaz.mp4, ./Foo Bar Baz.mp4)Remove
-nswitch, akadry-runwhen your attempts are satisfactory to rename for real.you even can inject calls in the
replacementpart, likesprintf "%03d", 7zero padding with theemodifier:$ 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
Perlish 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,
renameis 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
renamecommand existson macOS, the Homebrew packages
renameandutil-linuxconflicton macOS, the Homebrew package
renameoffers a Perl script that looks different from the otherson Arch Linux, the
perl-renamepackage offers a Perl script that's also different from the otherson Feroda, the
prenameoffers a Perl script that's also different from the otherson Debian,
prenameandfile-renameare alternatives forrenameon Ubuntu,
file-renameis the only alternative forrenamemksh 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). Therenamecommand will be available. If not, yourPATHdoes not include Perl script utilities. - for
Debian*, usedh-make-perl --build --cpan File::Renameto 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 prenameArch Linux/Manjaro:
pacman -S perl-renameGentoo:
emerge dev-perl/renameNixOs:
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-RenameAlpine Linux (in branch
edgeof thetestingrepository, not used by default):apk add perl-file-rename --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/macOS:
brew install renameDebian-like/Ubuntu:
apt install renameSlackware:
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
- 1(Coming from unix.stackexchange.com/a/757503/367454). In Alpine Linux, there is a package
perl-file-rename, but it is in thetestingrepository ofedgebranch and isn't installed by default. Furthermore, mksh hasrenameas 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– Vilinkameni2023-09-26 21:27:37 +00:00Commented Sep 26, 2023 at 21:27