| Crates.io | rnr |
| lib.rs | rnr |
| version | 0.5.0 |
| created_at | 2018-07-11 22:53:38.32918+00 |
| updated_at | 2025-01-12 15:52:22.803409+00 |
| description | RnR is a command-line tool to rename multiple files and directories that supports regular expressions |
| homepage | https://github.com/ismaelgv/rnr |
| repository | https://github.com/ismaelgv/rnr |
| max_upload_size | |
| id | 73841 |
| size | 115,347 |
RnR is a command-line tool to securely rename multiple files and directories that supports regular expressions.
You can download binaries from latest release page, choose the compressed file corresponding to your platform. These compressed files contain the executable and other additional content such as completion files (Bash, Zsh, fish and PowerShell).
A package is available in the AUR
(rnr) to install latest version of
RnR on Arch Linux.
You can use Homebrew package manager to install this tool in macOS or Linux systems.
brew install rnr
RnR is written in Rust. You can build it from source using Cargo.
git clone https://github.com/ismaelgv/rnr .
cargo install
cargo install rnr
Check a detailed description of the application usage and all its options using: rnr help.
regex crate. You can check regex syntax
here. It supports numbered and named capture
groups.from-file subcommand.NOTE: If the regular expression EXPRESSION contains - as initial
character, the application with parse it as an argument. You need to use --
after flags and before the arguments, for example rnr regex -f -- '-foo' '-bar' [...].
WINDOWS NOTE: In the examples that use *, you need to expand the wildcard
in PowerShell, for example: rnr regex a b (Get-Item ./*). This is not supported in
cmd.exe.
You can pass a list of files to be renamed as arguments:
rnr regex -f file renamed ./file-01.txt ./one/file-02.txt ./one/file-03.txt
Original tree
.
├── file-01.txt
├── file-02.txt
├── file-03.txt
└── one
├── file-01.txt
├── file-02.txt
└── file-03.txt
Renamed tree
.
├── renamed-01.txt
├── file-02.txt
├── file-03.txt
└── one
├── file-01.txt
├── renamed-02.txt
└── renamed-03.txt
Directories are ignored by default but you can also include them to be renamed using the option -D.
rnr regex -f -D foo bar ./*
Original tree
.
├── foo
│ └── foo.txt
└── foo.txt
Renamed tree
.
├── bar
│ └── foo.txt
└── bar.txt
The replacement limit is set to 1 by default, but you can configure this limit to replace multiple non-overlapping matches. All matches will be replaced if this option is set to 0.
rnr regex -f -l 0 o u ./*
Original tree
.
├── foo.txt
├── foofoo.txt
├── foofoofoo.txt
└── foofoofoofoo.txt
Renamed tree
.
├── fuu.txt
├── fuufuu.txt
├── fuufuufuu.txt
└── fuufuufuufuu.txt
You can combine rnr with other UNIX tools using pipes to pass arguments.
find . -type f +mtime 1 | xargs rnr regex -f file renamed
cat file_list.txt | xargs rnr regex -f file rename
file_list.txt content:
file-01.txt
one/file-02.txt
one/file-03.txt
If recursive (-r) option is passed, rnr will look for al files in the path recursively without depth limit.
rnr regex -f -r file renamed ./
Original tree
.
├── file-01.txt
├── file-02.txt
├── file-03.txt
└── one
├── file-01.txt
├── file-02.txt
├── file-03.txt
└── two
├── file-01.txt
├── file-02.txt
├── file-03.txt
└── three
├── file-01.txt
├── file-02.txt
└── file-03.txt
Renamed tree
.
├── renamed-01.txt
├── renamed-02.txt
├── renamed-03.txt
└── one
├── renamed-01.txt
├── renamed-02.txt
├── renamed-03.txt
└── two
├── renamed-01.txt
├── renamed-02.txt
├── renamed-03.txt
└── three
├── renamed-01.txt
├── renamed-02.txt
└── renamed-03.txt
Similarly, you can set a maximum directory depth in combination with recursive operations.
rnr regex -f -r -d 2 file renamed ./
Original tree
.
├── file-01.txt
├── file-02.txt
├── file-03.txt
└── one
├── file-01.txt
├── file-02.txt
├── file-03.txt
└── two
├── file-01.txt
├── file-02.txt
├── file-03.txt
└── three
├── file-01.txt
├── file-02.txt
└── file-03.txt
Renamed tree
.
├── renamed-01.txt
├── renamed-02.txt
├── renamed-03.txt
└── one
├── renamed-01.txt
├── renamed-02.txt
├── renamed-03.txt
└── two
├── file-01.txt
├── file-02.txt
├── file-03.txt
└── three
├── file-01.txt
├── file-02.txt
└── file-03.txt
rnr ignore hidden files by default to speed up the operations and avoid problems with some particular directories like .git/ or .local/. You can include hidden files passing -x option. Also, you can use include directories -D option with -r too.
rnr regex -f -r -D -x foo bar ./
Original tree
.
├── .foo_hidden_file.txt
├── foo.txt
├── foo
│ ├── foo.txt
│ └── foo
│ └── foo.txt
└── .foo_hidden_dir
└── foo.txt
Renamed tree
.
├── .bar_hidden_file.txt
├── bar.txt
├── bar
│ ├── bar.txt
│ └── bar
│ └── bar.txt
└── .bar_hidden_dir
└── bar.txt
When you perform a renaming operation, rnr will create by default a dump file in the current directory you executed the command. This file can be used to easily revert the operations using from-file and -u option.
Rename operation
rnr regex -f foo bar ./*
Undo previous operation
rnr from-file -f -u rnr-[timestamp].json
If you want to redo the operation just pass the dump file without any additional argument:
rnr from-file -f rnr-[timestamp].json
rnr can create backup files before renaming for any operation passing -b option. The backup files names are ensured to be unique and won't be overwritten if another backup is created. If you are working with many large files, take into account that files will be duplicated.
rnr regex -f -b file renamed ./*
Original tree
.
├── file-01.txt
├── file-02.txt
└── file-03.txt
Renamed tree
.
├── file-01.txt.bk
├── file-02.txt.bk
├── file-03.txt.bk
├── renamed-01.txt
├── renamed-02.txt
└── renamed-03.txt
rnrcan convert UTF-8 file names to their ASCII representation. This feature uses
AnyAscii library to perform the
transliteration.
You can run:
rnr to-ascii ./*
Or:
rnr to-ascii -r .
Original tree
.
├── fïlé-01.txt
├── FïĹÊ-02.txt
└── file-03.txt
Renamed tree
.
├── file-01.txt
├── FILE-02.txt
└── file-03.txt
More info about regex used in the regex package.
rnr regex -f '\..*$' '.txt' ./*
Original tree
.
├── file-01.ext1
├── file-02.ext2
└── file-03.ext3
Renamed tree
.
├── file-01.txt
├── file-02.txt
└── file-03.txt
rnr regex -f '\d' '1' ./*
Original tree
.
├── file-01.txt
├── file-02.txt
└── file-03.txt
Renamed tree
.
├── file-11.txt
├── file-12.txt
└── file-13.txt
name(1)-number(2).extension(3)].rnr regex -f '(\w+)-(\d+).(\w+)' '${2}-${1}.${3}' ./*
Original tree
.
├── file-01.txt
├── file-02.txt
└── file-03.txt
Renamed tree
.
├── 01-file.txt
├── 02-file.txt
└── 03-file.txt
SHELL NOTE: In shells like Bash and zsh, make sure to wrap the REPLACEMENT
pattern in single quotes. Otherwise, capture group indices will be replaced by
expanded shell variables.
number.ext.rnr regex -f '(?P<number>\d{2})\.(?P<ext>\w{3})' '${ext}.${number}' ./*
Original tree
.
├── file-01.txt
├── file-02.txt
└── file-03.txt
Renamed tree
.
├── file-txt.01
├── file-txt.02
└── file-txt.03
name(1)-number(2).extension(3)].rnr regex -f -t upper '(\w+)-(\d+)' '${2}-${1}' ./*
Original tree
.
├── file-01.txt
├── file-02.txt
└── file-03.txt
Renamed tree
.
├── 01-FILE.txt
├── 02-FILE.txt
└── 03-FILE.txt