rename
Wednesday, 4 Nov 2009 [Friday, 30 Aug 2019]
VERSION
SYNOPSIS
rename [switches|transforms] [files]
Switches:
- --man (read the full manual)
- -0/--null (when reading from STDIN)
- -f/--force or -i/--interactive (proceed or prompt when overwriting)
- -g/--glob (expand
*
etc. in filenames, useful in Windows™ CMD.EXE) - -k/--backwards/--reverse-order
- -l/--symlink or -L/--hardlink
- -M/--use=Module
- -n/--just-print/--dry-run
- -N/--counter-format
- -p/--mkpath/--make-dirs
- --stdin/--no-stdin
- -t/--sort-time
- -T/--transcode=encoding
- -v/--verbose
Transforms, applied sequentially:
- -a/--append=str
- -A/--prepend=str
- -c/--lower-case
- -C/--upper-case
- -d/--delete=str
- -D/--delete-all=str
- -e/--expr=code
- -P/--pipe=cmd
- -s/--subst from to
- -S/--subst-all from to
- -x/--remove-extension
- -X/--keep-extension
- -z/--sanitize
- --camelcase --urlesc --nows --rews --noctrl --nometa --trim (see manual)
DESCRIPTION
This program renames files according to modification rules specified on the command line. If no filenames are given on the command line, a list of filenames will be expected on standard input.
The documentation contains a "TUTORIAL".
OPTIONS
Switches
- -h, --help
-
See a synopsis.
- --man
-
Browse the manpage.
- -0, --null
-
When reading file names from
STDIN
, split on NUL bytes instead of newlines. This is useful in combination with GNU find's-print0
option, GNU grep's-Z
option, and GNU sort's-z
option, to name just a few. Only valid if no filenames have been given on the commandline. - -f, --force
-
Rename even when a file with the destination name already exists.
- -g, --glob
-
Glob filename arguments. This is useful if you're using a braindead shell such as cmd.exe which won't expand wildcards on behalf of the user.
- -i, --interactive
-
Ask the user to confirm every action before it is taken.
- -k, --backwards, --reverse-order
-
Process the list of files in reverse order, last file first. This prevents conflicts when renaming files to names which are currently taken but would be freed later during the process of renaming.
- -l, --symlink
-
Create symlinks from the new names to the existing ones, instead of renaming the files. Cannot be used in conjunction with
-L
. - -L, --hardlink
-
Create hard links from the new names to the existing ones, instead of renaming the files. Cannot be used in conjunction with
-l
. - -M, --use
-
Like perl's own
-M
switch. Loads the named modules at the beginning of the rename, and can pass import options separated by commata after an equals sign, i.e.Module=foo,bar
will pass thefoo
andbar
import options toModule
.You may load multiple modules by using this option multiple times.
- -n, --dry-run, --just-print
-
Show how the files would be renamed, but don't actually do anything.
- -N/--counter-format
-
Format and set the
$N
counter variable according to the given template.E.g.
-N 001
will make$N
start at 1 and be zero-padded to 3 digits, whereas-N 0099
will start the counter at 99 and zero-pad it to 4 digits. And so forth. Only digits are allowed in this simple form.As a special form, you can prefix the template with
...0
to indicate thatrename
should determine the width automatically based upon the number of files. E.g. if you pass-N ...01
along with 300 files,$N
will range from001
to300
. - -p, --mkpath, --make-dirs
-
Create any non-existent directories in the target path. This is very handy if you want to scatter a pile of files into subdirectories based on some part of their name (eg. the first two letters or the extension): you don't need to make all necessary directories beforehand, just tell
rename
to create them as necessary. - --stdin, --no-stdin
-
Always – or never – read the list of filenames from STDIN; do not guess based on the presence or absence of filename arguments. Filename arguments must not be present when using
--stdin
. - -T, --transcode
-
Decode each filename before processing and encode it after processing, according to the given encoding supplied.
To encode output in a different encoding than input was decoded, supply two encoding names, separated by a colon, e.g.
-T latin1:utf-8
.Only the last
-T
parameter on the command line is effective. - -v, --verbose
-
Print additional information about the operations (not) executed.
Transforms
Transforms are applied to filenames sequentially. You can use them multiple times; their effects will accrue.
- -a, --append
-
Append the string argument you supply to every filename.
- -A, --prepend
-
Prepend the string argument you supply to every filename.
- -c, --lower-case
-
Convert file names to all lower case.
- -C, --upper-case
-
Convert file names to all upper case.
- -e, --expr
-
The
code
argument to this option should be a Perl expression that assumes the filename in the$_
variable and modifies it for the filenames to be renamed. When no other-c
,-C
,-e
,-s
, or-z
options are given, you can omit the-e
from infront of the code. - -P, --pipe
-
Pass the filename to an external command on its standard input and read back the transformed filename on its standard output.
- -s, --subst
-
Perform a simple textual substitution of
from
toto
. Thefrom
andto
parameters must immediately follow the argument. - -S, --subst-all
-
Same as
-s
, but replaces every instance of thefrom
text by theto
text. - -x, --remove-extension
-
Remove the last extension from a filename, if there is any.
- -X, --keep-extension
-
Save and remove the last extension from a filename, if there is any. The saved extension will be appended back to the filename at the end of the rest of the operations.
Repeating this option will save multiple levels of extension in the right order.
- -z, --sanitize
-
A shortcut for passing
--nows --noctrl --nometa --trim
. - --camelcase
-
Capitalise every separate word within the filename.
- --urlesc
-
Decode URL-escaped filenames, such as wget(1) used to produce.
- --nows
-
Replace all sequences of whitespace in the filename with single underscore characters.
- --rews
-
Reverse
--nows
: replace each underscore in the filename with a space. - --noctrl
-
Replace all sequences of control characters in the filename with single underscore characters.
- --nometa
-
Replace every shell meta-character with an underscore.
- --trim
-
Remove any sequence of spaces and underscores at the left and right ends of the filename.
VARIABLES
These predefined variables are available for use within any -e
expressions you pass.
- $N
-
A counter that increments for each file in the list. By default, counts up from 1.
The
-N
switch takes a template that specifies the padding and starting value of$N
; see "Switches". - $EXT
-
A string containing the accumulated extensions saved by
-X
switches, without a leading dot. See "Switches". - @EXT
-
An array containing the accumulated extensions saved by
-X
switches, from right to left, without any dots.The right-most extension is always
$EXT[0]
, the left-most (if any) is$EXT[-1]
.
TUTORIAL
rename takes a list of filenames, runs a list of modification rules against each filename, checks if the result is different from the original filename, and if so, renames the file. The most flexible way to use it is to pass a line of Perl code as the rule; the most convenient way is to employ the many switches available to supply rules for common tasks such as stripping extensions.
For example, to strip the extension from all .bak
files, you might use either of these command lines:
rename -x *.bak
rename 's/\.bak\z//' *
These do not achive their results in exactly the same way: the former only takes the files that match *.bak
in the first place, then strips their last extension; the latter takes all files and strips a .bak
from the end of those filenames that have it. As another alternative, if you are confident that none of the filenames has .bak
anywhere else than at the end, you might instead choose to write the latter approach using the -s
switch:
rename -s .bak '' *
Of course you can do multiple changes in one go:
rename -s .tgz .tar.gz -s .tbz2 .tar.bz2 *.t?z*
But note that transforms are order sensitive. The following will not do what you probably meant:
rename -s foo bar -s bar baz *
Because rules are cumulative, this would first substitute foo with bar; in the resulting filenames, it would then substitute bar with baz. So in most cases, it would end up substituting foo with baz – probably not your intention. So you need to consider the order of rules.
If you are unsure that your modification rules will do the right thing, try doing a verbose dry run to check what its results would be. A dry run is requested by passing -n
:
rename -n -s bar baz -s foo bar *
You can combine the various transforms to suit your needs. E.g. files from Microsoft™ Windows™ systems often have blanks and (sometimes nothing but) capital letters in their names. Let's say you have a heap of such files to clean up, and you also want to move them to subdirectories based on extension. The following command will do this for you:
rename -p -c -z -X -e '$_ = "$EXT/$_" if @EXT' *
Here, -p
tells rename to create directories if necessary; -c
tells it to lower-case the filename; -X
remembers the file extension in the $EXT
and @EXT
variables; and finally, the -e
expression uses those to prepend the extension to the filename as a directory, if there is one.
That brings us to the secret weapon in rename's arsenal: the -X
switch. This is a transform that clips the extension off the filename and stows it away at that point during the application of the rules. After all rules are finished, the remembered extension is appended back onto the filename. (You can use multiple -X
switches, and they will accumulate multiple extensions as you would expect.) This allows you to do use simple way for doing many things that would get much trickier if you had to make sure to not affect the extension. E.g.:
rename -X -c --rews --camelcase --nows *
This will uppercase the first letter of every word in every filename while leaving its extension exactly as before. Or, consider this:
rename -N ...01 -X -e '$_ = "File-$N"' *
This will throw away all the existing filenames and simply number the files from 1 through however many files there are – except that it will preserve their extensions.
Incidentally, note the -N
switch and the $N
variable used in the Perl expression. See "Switches" and "VARIABLES" for documentation.
COOKBOOK
Recursive renaming in subdirectories
Since rename only operates on file names given on the command line, it may not be obvious how it can be used to rename files recursively in subdirectories: using tools outside of rename.
The portable option is to pipe a list of file names to it already:
find somedir -print0 | rename -0 -e 'print "$_\n"'
But when you invoke rename from zsh or from a semi-recent bash with the globstar
option enabled, you can use double asterisks in your globs to make them recursive:
rename -e 'print "$_\n"' somedir/**
Note that rename will then operate on the entire path, not just the filename. (A future version of rename may add mechanisms to address this.)
Putting the CPAN to use
Using the -M
switch, you can quickly put rename to use for just about everything the CPAN offers:
Coarsely latinize a directory full of files with non-Latin characters
rename -T utf8 -MText::Unidecode '$_ = unidecode $_' *
See Text::Unidecode.
Sort a directory of pictures into monthwise subdirectories
rename -p -MImage::EXIF '$_ = "$1-$2/$_" if Image::EXIF->new->file_name($_)
->get_image_info->{"Image Created"} =~ /(\d\d\d\d):(\d\d)/' *.jpeg
# or
rename -p -MImage::ExifTool=:Public '$_ = "$1-$2/$_"
if ImageInfo($_)->{"CreateDate"} =~ /(\d\d\d\d):(\d\d)/' *.jpeg
See Image::EXIF, Image::ExifTool.
Fix up mail attachments stored under MIME-encoded names
rename -MEncode '$_=decode "MIME-Header", $_ if /^=/' =*
See Encode::MIME::Header.
SEE ALSO
mv(1), perl(1), find(1), grep(1), sort(1)
BUGS
None currently known.
AUTHORS
Aristotle Pagaltzis
Idea, inspiration and original code from Larry Wall and Robin Barker.
COPYRIGHT
This script is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Referenced in rename
1.600, rename
1.601.