RnR is a command-line tool to securely rename multiple files and directories that supports regular expressions

Overview

rnr

Build Status Crates.io License

RnR is a command-line tool to securely rename multiple files and directories that supports regular expressions.

Features

  • Batch rename files and directories.
  • Automated checks to avoid unwanted file collisions, removals or overwrites.
  • Use regexp, including capture groups.
  • Include directories recursively.
  • Create backup files.
  • Create and read operations from dump file.
  • Undo operations from dump file.
  • Exclude/include hidden files.
  • Linux, Mac and Windows support, including terminal coloring.
  • Extensive unit testing.
  • Select limit of replacements.
  • Convert UTF-8 file names to ASCII representation.

Install

Binaries

GitHub Releases

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).

Arch Linux

A package is available in the AUR (rnr) to install latest version of RnR on Arch Linux.

From Source

RnR is written in Rust. You can build it from source using Cargo.

From git repository

git clone https://github.com/ismaelgv/rnr .
cargo install

From Crates.io

cargo install rnr

Usage

Options

USAGE:
    rnr [FLAGS] [OPTIONS] 
    
     
     
      ...
    rnr [FLAGS] [OPTIONS] 
      
       

FLAGS:
    -b, --backup          Generate file backups before renaming
    -n, --dry-run         Only show what would be done (default mode)
        --dump            Force dumping operations into a file even in dry-run mode
    -f, --force           Make actual changes to files
    -h, --help            Prints help information
    -x, --hidden          Include hidden files and directories
    -D, --include-dirs    Rename matching directories
        --no-dump         Do not dump operations into a file
    -r, --recursive       Recursive mode
    -s, --silent          Do not print any information
    -V, --version         Prints version information

OPTIONS:
        --color 
       
         Set color output mode [default: auto] [possible values: always, auto, never] -d, --max-depth 
        
          Set max depth in recursive mode -l, --replace-limit 
         
           Limit of replacements, all matches if set to 0 [default: 1] ARGS: 
          
            Expression to match (can be a regex) 
           
             Expression replacement 
            
             ... Target paths SUBCOMMANDS: from-file Read operations from a dump file help Prints this message or the help of the given subcommand(s) to-ascii Replace all file name chars with ASCII chars. This operation is extremely lossy. 
            
           
          
         
        
       
      
     
    
   

Default behavior

  • Checks all operations to avoid overwriting existing files.
  • Dry-run by default.
  • Only UTF-8 valid input arguments and filenames.
  • Works on files and symlinks (ignores directories).
  • Accepts multiple files as arguments.
  • Accepts a regex to generate matches. These expressions have same limitations of regex crate. You can check regex syntax here. It supports numbered and named capture groups.
  • If max depth is not provided to recursive mode, it is assumed infinite.
  • Does not generate backups.
  • Output is colored (only ANSI terminals).
  • Ignore hidden files and directories.
  • Dump all operations into a file in force mode. This dump file can be used to undo these operations from from-file subcommand.
  • Number of replacements set to one.

Examples

WINDOWS NOTE: In the examples that use *, you need to expand the wildcard in PowerShell, for example: rnr a b (Get-Item ./*). This is not supported in cmd.exe.

Rename a list of files

You can pass a list of files to be renamed as arguments:

rnr -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

Include directories

Directories are ignored by default but you can also include them to be renamed using the option -D.

rnr -f -D foo bar ./*

Original tree

.
├── foo
│   └── foo.txt
└── foo.txt

Renamed tree

.
├── bar
│   └── foo.txt
└── bar.txt

Multiple replacements

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 -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

Combination with other UNIX tools

You can combine rnr with other UNIX tools using pipes to pass arguments.

Find files older than 1 day and rename them
find . -type f +mtime 1 | xargs rnr -f file renamed
Read list of files from a file
cat file_list.txt | xargs rnr -f file rename

file_list.txt content:

file-01.txt
one/file-02.txt
one/file-03.txt

Recursive rename

If recursive (-r) option is passed, rnr will look for al files in the path recursively without depth limit.

rnr -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

Recursive rename with max directory depth

Similarly, you can set a maximum directory depth in combination with recursive operations.

rnr -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

Recursive rename including directories and hidden files

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 -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

Undo/redo operations using dump file

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 -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

Create backup files before renaming

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 -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

Convert UTF-8 file names to ASCII

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

Advanced regex examples

More info about regex used in the regex package.

Replace extensions

rnr -f '\..*$' '.txt' ./*

Original tree

.
├── file-01.ext1
├── file-02.ext2
└── file-03.ext3

Renamed tree

.
├── file-01.txt
├── file-02.txt
└── file-03.txt

Replace numbers

rnr -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

Capture groups

  1. Capture three unnamed groups [name(1)-number(2).extension(3)].
  2. Swap group 1 (name) and group 2 (number).
rnr -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

Capture several named groups and swap them

  1. Capture two digits as number.
  2. Capture extension as ext.
  3. Swap groups.
rnr -f '(?P
   
    \d{2})\.(?P
    
     \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
Comments
  • Regex replacement doesn't work in cmd.exe, only in sh.exe

    Regex replacement doesn't work in cmd.exe, only in sh.exe

    Context (like in the other issue): About a year ago, Diesel changed the name format of the migrations that it generates. I still have many migrations in the old format and want to use rnr to rename them into the new format.

    At first I tried to run this in cmd.exe: rnr -D '(\d{4})(\d{2})(\d{2})(\d{6})' '$1-$2-$3-$4' ./* in my migrations folder, but it didn't show any matches/replacements, only This is a DRY-RUN. I also tried with double quotes, but I got the same result (no matches/replacements) :/ (When I execute it in the sh.exe of the Git Shell (powershell) of GitHub Desktop for Windows, it works, but it's very inconvenient..) Is there a way to make it work in cmd.exe, too?

    cannot reproduce 
    opened by Boscop 10
  • ascii restriction mode

    ascii restriction mode

    Issue Description

    i am using this tool mainly to fix filesystem issues that i am having after working with different files from different sources, an example being files using UTF-8 character set outside the standard ascii range like Asian, Slavic, extended Latin or German special characters (i.e. 'ąłśćż' ). Those files while working on modern file systems like btrfs without a problem but in some cases, for example when being copied or transferred to file systems not supporting UTF-8 out of the box, it's erroneous or just prevents me from doing so, since the drivers do not know what to do with those. Here comes the RnR which i use to strip those as far as i am able to, but it takes some wizardry to do properly and i am still not sure if i am not overlooked something. Also, it's extremely lossy at this moment.

    Resolution Proposition

    there is an library that translates the special characters to ASCII bound ones - https://github.com/anyascii/anyascii can we get a flag that for example in addition to running regexp, forces the special characters to be conversed to the ascii ones? for example, --restrict

    this issue is related mainly to unix/linux platform.

    enhancement 
    opened by esavier 8
  • Support change of case on case-insensitive file systems

    Support change of case on case-insensitive file systems

    On Windows, with a case-insensitive but case-preserving file-system, what's the best way to change the case of a file?

    For example, this command produces an error message:

    $ rnr -f .JPG$ .jpg image.JPG
    Error: Conflict with existing path image.JPG -> image.jpg
    

    Currently I'm renaming via a temp file name (eg, rename to .jpg.tmp, then strip out the .tmp). Maybe this would work if the conflict detection ignored the source file when checking to see if the target file exists, which is kind of an edge case due to case-insensitivity where the source file won't conflict once it has been renamed.

    opened by DouglasLivingstone 4
  • [Feature request] Highlight replacements in dry-run mode.

    [Feature request] Highlight replacements in dry-run mode.

    Hi, thanks for rnr!

    It would be nice to highlight in color what is replaced with what in a dry-run mode.

    Useful cases:

    • files / directories with long names (surely human brain parses colors way faster than long symbol sequences, and then you also need to diff both paths!)
    • replacement occurs multiple times

    That's how ripgrep highlights found matches by default, for instance (rg fn):

    image

    Or another toy example (echo barfoobar | rg bar --replace baz): image

    What do you think?

    enhancement 
    opened by murlakatamenka 3
  • regexp in windows

    regexp in windows

    precondition:

    • windows 7 x86

    Pattern "strin" should be changed to pattern "strout" in current directory Does not work next command rnr -n -r strin strout ./* but the workaround with recursive option and dept=1 works well: rnr -n -r -d 1 strin strout ./

    next issue
    regexp with single quotes does not work correct, rnr -n -r -d 1 '(.+)\.d(\w+)' '${1}' ./ but double quotes works well rnr -n -r -d 1 "(.+)\.d(\w+)" "${1}" ./

    opened by mikowiec 2
  • How to do `git mv` for renaming?

    How to do `git mv` for renaming?

    About a year ago, Diesel changed the name format of the migrations that it generates. I still have many migrations in the old format and want to use rnr to rename them into the new format. But how can I do the renaming with git mv so that git properly recognizes that the folders were renamed? If I just do rnr -f -D '(\d{4})(\d{2})(\d{2})(\d{6})' '$1-$2-$3-$4' ./*, git shows the files as being removed and new files added. When I use git mv manually, it correctly shows them as renamed..

    question 
    opened by Boscop 2
  • Fix README.md example output

    Fix README.md example output

    Looks like there's a copy paste error in one of the examples in the README file. Running the example command for real does what you'd expect it too:

    > tree
    .
    ├── file-01.txt
    ├── file-02.txt
    ├── file-03.txt
    └── one
        ├── file-01.txt
        ├── file-02.txt
        └── file-03.txt
    
    1 directory, 6 files
    > rnr -f file renamed ./file-01.txt ./one/file-02.txt ./one/file-03.txt
    ./one/file-03.txt -> ./one/renamed-03.txt
    ./one/file-02.txt -> ./one/renamed-02.txt
    ./file-01.txt -> ./renamed-01.txt
    > tree
    .
    ├── file-02.txt
    ├── file-03.txt
    ├── one
    │   ├── file-01.txt
    │   ├── renamed-02.txt
    │   └── renamed-03.txt
    ├── renamed-01.txt
    └── rnr-2020-07-17_213630.json
    

    1 directory, 7 files

    opened by seanwatson 1
  • [Feature request] Add file names enumeration (counter) option

    [Feature request] Add file names enumeration (counter) option

    For example I have some files: sadasd.png, asdjklsa,png, kflsadl.png And I want to rename them to: 1.png, 2.png, 3.png So as far as I know in current state it's impossible to do it? P.S. Yeah, I know there are tons of tools that can do it but I'm interested in rnr only because it has working in cmd undo feature.

    opened by suphamster 3
  • Support for non-valid UTF-8 strings

    Support for non-valid UTF-8 strings

    Extend code to support non-valid UTF-8 strings in filenames, paths and arguments:

    • Use OsStr and OsString.
    • Follow OsStr pattern API extension in Rust repository.
    • Check issues with current crates: clap, regex, walkdir and ansi_term
    enhancement 
    opened by ismaelgv 2
Releases(v0.4.1)
Owner
Ismael González Valverde
Simplify, rinse and repeat.
Ismael González Valverde
Rust library for regular expressions using "fancy" features like look-around and backreferences

fancy-regex A Rust library for compiling and matching regular expressions. It uses a hybrid regex implementation designed to support a relatively rich

fancy-regex 302 Jan 3, 2023
😎 Pretty way of writing regular expressions in Rust

?? Write readable regular expressions The crate provides a clean and readable way of writing your regex in the Rust programming language: Without pret

Adi Salimgereyev 7 Aug 12, 2023
A CLI tool to rename files to randomly generated strings.

rng-rename A CLI tool to rename files to randomly generated strings. Why? Suppose you downloaded a few hundred images to use as your desktop wallpaper

null 2 Feb 24, 2022
Rsre it's tool to rename file/directory

, Rust renamer Rsre it's tool to rename file/directory Zero dependencies ?? Requirements Rust Nightly Install With Cargo # Install nightly rust rustup

Awiteb 6 Dec 22, 2022
Voila is a domain-specific language launched through CLI tool for operating with files and directories in massive amounts in a fast & reliable way.

Voila is a domain-specific language designed for doing complex operations to folders & files. It is based on a CLI tool, although you can write your V

Guillem Jara 86 Dec 12, 2022
A cli tool to download specific GitHub directories or files

cloneit A cli tool to download specific GitHub directories or files. Installation From git git clone https://github.com/alok8bb/cloneit cd cloneit car

Alok 54 Dec 20, 2022
A command line tool for easily generating multiple versions of a configuration file from a single template

MultiConf A command line tool for easily generating multiple versions of a configuration file from a single template. Why? I'm a big fan of the i3 win

Ian Clarke 4 Dec 10, 2022
Tool and framework for securely reading untrusted USB mass storage devices.

usbsas is a free and open source (GPLv3) tool and framework for securely reading untrusted USB mass storage devices. Description Following the concept

CEA IT Security 250 Aug 16, 2023
Small command-line tool to switch monitor inputs from command line

swmon Small command-line tool to switch monitor inputs from command line Installation git clone https://github.com/cr1901/swmon cargo install --path .

William D. Jones 5 Aug 20, 2022
Temporary files and directories with UTF-8 paths.

camino-tempfile A secure, cross-platform, temporary file library for Rust with UTF-8 paths. This crate is a wrapper around tempfile that works with th

null 4 Apr 24, 2023
Remove files or directories.

Wrm - Remove files or directories Installation Run the following Cargo command: cargo install wrm Usage To move files to trash($HOME/.local/share/wrm

null 41 Mar 4, 2024
🍅 A command-line tool to get and set values in toml files while preserving comments and formatting

tomato Get, set, and delete values in TOML files while preserving comments and formatting. That's it. That's the feature set. I wrote tomato to satisf

C J Silverio 15 Dec 23, 2022
rsv is a command line tool to deal with small and big CSV, TXT, EXCEL files (especially >10G)

csv, excel toolkit written in Rust rsv is a command line tool to deal with small and big CSV, TXT, EXCEL files (especially >10G). rsv has following fe

Zhuang Dai 39 Jan 30, 2023
Tool for managing dotfiles directories; Heavily based on rcm.

Paro paro : to prepare, get ready / set, put / furnish, supply. Tool for managing dotfiles directories; Heavily based on rcm. TODO Rust Boilerplate CI

Rafael Delboni 7 Nov 20, 2022
Command line tool to extract various data from Blender .blend files

blendtool Command line tool to extract various data from Blender .blend files. Currently supports dumping Eevee irradiance volumes to .dds, new featur

null 2 Sep 26, 2021
apkeep - A command-line tool for downloading APK files from various sources

apkeep - A command-line tool for downloading APK files from various sources Installation Precompiled binaries for apkeep on various platforms can be d

Electronic Frontier Foundation 561 Dec 29, 2022
Anglosaxon is a command line tool to parse XML files using SAX

anglosaxon - Convert large XML files to other formats anglosaxon is a command line tool to parse XML files using SAX. You can do simple transformation

Amanda 8 Oct 7, 2022
Command line tool for editing .ini files

Edit-ini Command line tool for editing .ini files Usage Usage: edit-ini [OPTIONS] Options: -i, --input <file> Input file to read f

null 3 Dec 28, 2022
Potr (Po Translator) is a command line tool for translating gettext PO files.

Potr Potr (Po Translator) is a command line tool for translating Gettext PO files. Currently, it supports translation using OpenAI, Azure OpenAI Servi

Riff 6 Jul 16, 2023