{"id":13539552,"url":"https://github.com/ismaelgv/rnr","last_synced_at":"2025-10-21T04:43:10.501Z","repository":{"id":44847794,"uuid":"140597469","full_name":"ismaelgv/rnr","owner":"ismaelgv","description":"A command-line tool to batch rename files and directories","archived":false,"fork":false,"pushed_at":"2023-11-28T21:14:56.000Z","size":244,"stargazers_count":429,"open_issues_count":6,"forks_count":17,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-07-11T12:01:55.943Z","etag":null,"topics":["rename-files","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ismaelgv.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-11T15:48:44.000Z","updated_at":"2024-08-01T09:23:16.860Z","dependencies_parsed_at":"2023-11-28T22:27:19.041Z","dependency_job_id":"67485048-3c3b-4dde-8d25-e95f8ab23e84","html_url":"https://github.com/ismaelgv/rnr","commit_stats":{"total_commits":233,"total_committers":3,"mean_commits":77.66666666666667,"dds":"0.012875536480686733","last_synced_commit":"dfdf644ea8a4084ec73a349de68ef063eb47028f"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ismaelgv%2Frnr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ismaelgv%2Frnr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ismaelgv%2Frnr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ismaelgv%2Frnr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ismaelgv","download_url":"https://codeload.github.com/ismaelgv/rnr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246495133,"owners_count":20786885,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rename-files","rust"],"created_at":"2024-08-01T09:01:27.747Z","updated_at":"2025-10-21T04:43:05.249Z","avatar_url":"https://github.com/ismaelgv.png","language":"Rust","funding_links":[],"categories":["Rust","Applications","Command Line Tools"],"sub_categories":["System tools"],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://user-images.githubusercontent.com/8478202/107156909-59030580-6981-11eb-9374-95959b6ec067.png\" width=\"350\" height=\"350\" alt=\"rnr\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/ismaelgv/rnr/actions?query=workflow%3ARnR\"\u003e\n        \u003cimg src=\"https://github.com/ismaelgv/rnr/workflows/RnR/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://crates.io/crates/rnr\"\u003e\n        \u003cimg src=\"https://img.shields.io/crates/v/rnr.svg\" alt=\"Crates.io\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/ismaelgv/rnr/blob/master/LICENSE\"\u003e\n        \u003cimg src=\"https://img.shields.io/crates/l/rnr.svg\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cb\u003eRnR\u003c/b\u003e is a command-line tool to \u003cb\u003esecurely rename\u003c/b\u003e multiple files\n    and directories that supports regular expressions.\n\u003c/p\u003e\n\n## Features\n* Batch rename files and directories.\n* Automated checks to avoid unwanted file collisions, removals or overwrites.\n* Use regexp, including capture groups.\n* Include directories recursively.\n* Create backup files.\n* Create and read operations from dump file.\n* Undo operations from dump file.\n* Exclude/include hidden files.\n* Linux, Mac and Windows support, including terminal coloring.\n* Extensive unit testing.\n* Select limit of replacements.\n* Convert UTF-8 file names to ASCII representation.\n\n# Install\n\n## Binaries\n\n### GitHub Releases\nYou can download binaries from [latest release\npage](https://github.com/ismaelgv/rnr/releases), choose the compressed\nfile corresponding to your platform. These compressed files contain the\nexecutable and other additional content such as completion files (*Bash*, *Zsh*,\n*fish* and *PowerShell*).\n\n### Arch Linux\nA package is available in the AUR\n([`rnr`](https://aur.archlinux.org/packages/rnr/)) to install latest version of\n*RnR* on Arch Linux.\n\n### Homebrew\nYou can use [Homebrew package manager](https://brew.sh) to install this tool in macOS or Linux systems.\n```sh\nbrew install rnr\n```\n\n## From Source\n*RnR* is written in Rust. You can build it from source using Cargo.\n\n### From git repository\n```sh\ngit clone https://github.com/ismaelgv/rnr .\ncargo install\n```\n### From Crates.io\n```sh\ncargo install rnr\n```\n# Usage\n## Options\n```\nUSAGE:\n    rnr [FLAGS] [OPTIONS] \u003cEXPRESSION\u003e \u003cREPLACEMENT\u003e \u003cPATH(S)\u003e...\n    rnr [FLAGS] [OPTIONS] \u003cSUBCOMMAND\u003e\n\nFLAGS:\n    -b, --backup          Generate file backups before renaming\n    -n, --dry-run         Only show what would be done (default mode)\n        --dump            Force dumping operations into a file even in dry-run mode\n    -f, --force           Make actual changes to files\n    -h, --help            Prints help information\n    -x, --hidden          Include hidden files and directories\n    -D, --include-dirs    Rename matching directories\n        --no-dump         Do not dump operations into a file\n    -r, --recursive       Recursive mode\n    -s, --silent          Do not print any information\n    -V, --version         Prints version information\n\nOPTIONS:\n        --color \u003ccolor\u003e            Set color output mode [default: auto]  [possible values: always, auto, never]\n    -d, --max-depth \u003cLEVEL\u003e        Set max depth in recursive mode\n    -l, --replace-limit \u003cLIMIT\u003e    Limit of replacements, all matches if set to 0 [default: 1]\n\nARGS:\n    \u003cEXPRESSION\u003e     Expression to match (can be a regex)\n    \u003cREPLACEMENT\u003e    Expression replacement\n    \u003cPATH(S)\u003e...     Target paths\n\nSUBCOMMANDS:\n    from-file    Read operations from a dump file\n    help         Prints this message or the help of the given subcommand(s)\n    to-ascii     Replace all file name chars with ASCII chars. This operation is extremely lossy.\n```\n\n## Default behavior\n* Checks all operations to avoid overwriting existing files.\n* *Dry-run* by default.\n* Only **UTF-8 valid** input arguments and filenames.\n* Works on files and symlinks (ignores directories).\n* Accepts multiple files as arguments.\n* Accepts a **regex** to generate matches. These expressions have same\n  limitations of `regex` crate. You can check regex syntax\n  [here](https://docs.rs/regex/#syntax). It supports numbered and named *capture\n  groups*.\n* If max depth is not provided to recursive mode, it is assumed *infinite*.\n* Does not generate backups.\n* Output is *colored* (only ANSI terminals).\n* Ignore hidden files and directories.\n* Dump all operations into a file in force mode. This dump file can be used to\n  undo these operations from `from-file` subcommand.\n* Number of replacements set to one.\n\n## Examples\n* [Rename a list of files](#rename-a-list-of-files)\n    * [Include directories](#include-directories)\n    * [Multiple replacements](#multiple-replacements)\n    * [Combination with other UNIX tools](#combination-with-other-unix-tools)\n* [Recursive rename](#recursive-rename)\n    * [Recursive rename with max directory depth](#recursive-rename-with-max-directory-depth)\n    * [Recursive rename including directories and hidden files](#recursive-rename-including-directories-and-hidden-files)\n* [Undo/redo operations using dump file](#undoredo-operations-using-dump-file)\n* [Create backup files before renaming](#create-backup-files-before-renaming)\n* [Convert UTF-8 file names to ASCII](#convert-utf-8-file-names-to-ascii)\n* [Advanced regex examples](#advanced-regex-examples)\n    * [Replace extensions](#replace-extensions)\n    * [Replace numbers](#replace-numbers)\n    * [Capture groups](#capture-groups)\n    * [Capture several named groups and swap them](#capture-several-named-groups-and-swap-them)\n\n__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`.\n\n### Rename a list of files\nYou can pass a list of files to be renamed as arguments:\n```sh\nrnr -f file renamed ./file-01.txt ./one/file-02.txt ./one/file-03.txt\n```\n*Original tree*\n```\n.\n├── file-01.txt\n├── file-02.txt\n├── file-03.txt\n└── one\n    ├── file-01.txt\n    ├── file-02.txt\n    └── file-03.txt\n```\n*Renamed tree*\n```\n.\n├── renamed-01.txt\n├── file-02.txt\n├── file-03.txt\n└── one\n    ├── file-01.txt\n    ├── renamed-02.txt\n    └── renamed-03.txt\n```\n\n#### Include directories\nDirectories are ignored by default but you can also include them to be renamed using the option `-D`.\n```sh\nrnr -f -D foo bar ./*\n```\n*Original tree*\n```\n.\n├── foo\n│   └── foo.txt\n└── foo.txt\n```\n*Renamed tree*\n```\n.\n├── bar\n│   └── foo.txt\n└── bar.txt\n```\n\n#### Multiple replacements\nThe replacement limit is set to 1 by default, but you can configure this limit\nto replace multiple non-overlapping matches. All matches will be replaced if\nthis option is set to 0.\n\n```sh\nrnr -f -l 0 o u ./*\n```\n*Original tree*\n```\n.\n├── foo.txt\n├── foofoo.txt\n├── foofoofoo.txt\n└── foofoofoofoo.txt\n```\n*Renamed tree*\n```\n.\n├── fuu.txt\n├── fuufuu.txt\n├── fuufuufuu.txt\n└── fuufuufuufuu.txt\n```\n\n#### Combination with other UNIX tools\nYou can combine `rnr` with other UNIX tools using pipes to pass arguments.\n\n##### Find files older than 1 day and rename them\n```sh\nfind . -type f +mtime 1 | xargs rnr -f file renamed\n```\n\n##### Read list of files from a file\n```sh\ncat file_list.txt | xargs rnr -f file rename\n```\n\n`file_list.txt` content:\n```\nfile-01.txt\none/file-02.txt\none/file-03.txt\n```\n\n### Recursive rename\nIf recursive (`-r`) option is passed, `rnr` will look for al files in the path recursively without depth limit.\n```sh\nrnr -f -r file renamed ./\n```\n*Original tree*\n```\n.\n├── file-01.txt\n├── file-02.txt\n├── file-03.txt\n└── one\n    ├── file-01.txt\n    ├── file-02.txt\n    ├── file-03.txt\n    └── two\n        ├── file-01.txt\n        ├── file-02.txt\n        ├── file-03.txt\n        └── three\n            ├── file-01.txt\n            ├── file-02.txt\n            └── file-03.txt\n```\n*Renamed tree*\n```\n.\n├── renamed-01.txt\n├── renamed-02.txt\n├── renamed-03.txt\n└── one\n    ├── renamed-01.txt\n    ├── renamed-02.txt\n    ├── renamed-03.txt\n    └── two\n        ├── renamed-01.txt\n        ├── renamed-02.txt\n        ├── renamed-03.txt\n        └── three\n            ├── renamed-01.txt\n            ├── renamed-02.txt\n            └── renamed-03.txt\n```\n#### Recursive rename with max directory depth\nSimilarly, you can set a maximum directory depth in combination with recursive operations.\n```sh\nrnr -f -r -d 2 file renamed ./\n```\n*Original tree*\n```\n.\n├── file-01.txt\n├── file-02.txt\n├── file-03.txt\n└── one\n    ├── file-01.txt\n    ├── file-02.txt\n    ├── file-03.txt\n    └── two\n        ├── file-01.txt\n        ├── file-02.txt\n        ├── file-03.txt\n        └── three\n            ├── file-01.txt\n            ├── file-02.txt\n            └── file-03.txt\n```\n*Renamed tree*\n```\n.\n├── renamed-01.txt\n├── renamed-02.txt\n├── renamed-03.txt\n└── one\n    ├── renamed-01.txt\n    ├── renamed-02.txt\n    ├── renamed-03.txt\n    └── two\n        ├── file-01.txt\n        ├── file-02.txt\n        ├── file-03.txt\n        └── three\n            ├── file-01.txt\n            ├── file-02.txt\n            └── file-03.txt\n```\n\n#### Recursive rename including directories and hidden files\n`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.\n```sh\nrnr -f -r -D -x foo bar ./\n```\n*Original tree*\n```\n.\n├── .foo_hidden_file.txt\n├── foo.txt\n├── foo\n│   ├── foo.txt\n│   └── foo\n│       └── foo.txt\n└── .foo_hidden_dir\n    └── foo.txt\n```\n*Renamed tree*\n```\n.\n├── .bar_hidden_file.txt\n├── bar.txt\n├── bar\n│   ├── bar.txt\n│   └── bar\n│       └── bar.txt\n└── .bar_hidden_dir\n    └── bar.txt\n```\n\n### Undo/redo operations using dump file\nWhen 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.\n\n*Rename operation*\n```sh\nrnr -f foo bar ./*\n```\n*Undo previous operation*\n```sh\nrnr from-file -f -u rnr-[timestamp].json\n```\n\nIf you want to redo the operation just pass the dump file without any additional argument:\n```sh\nrnr from-file -f rnr-[timestamp].json\n\n```\n\n### Create backup files before renaming\n`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.\n\n```sh\nrnr -f -b file renamed ./*\n```\n\n*Original tree*\n```\n.\n├── file-01.txt\n├── file-02.txt\n└── file-03.txt\n```\n*Renamed tree*\n```\n.\n├── file-01.txt.bk\n├── file-02.txt.bk\n├── file-03.txt.bk\n├── renamed-01.txt\n├── renamed-02.txt\n└── renamed-03.txt\n```\n\n### Convert UTF-8 file names to ASCII\n`rnr`can convert UTF-8 file names to their ASCII representation. This feature uses\n[AnyAscii library](https://github.com/anyascii/anyascii) to perform the\ntransliteration.\n\nYou can run:\n```sh\nrnr to-ascii ./*\n```\nOr:\n```sh\nrnr to-ascii -r .\n```\n\n*Original tree*\n```\n.\n├── fïlé-01.txt\n├── FïĹÊ-02.txt\n└── file-03.txt\n```\n*Renamed tree*\n```\n.\n├── file-01.txt\n├── FILE-02.txt\n└── file-03.txt\n```\n\n### Advanced regex examples\nMore info about regex used [in the `regex` package](https://docs.rs/regex).\n#### Replace extensions\n```\nrnr -f '\\..*$' '.txt' ./*\n```\n*Original tree*\n```\n.\n├── file-01.ext1\n├── file-02.ext2\n└── file-03.ext3\n```\n*Renamed tree*\n```\n.\n├── file-01.txt\n├── file-02.txt\n└── file-03.txt\n```\n\n#### Replace numbers\n```\nrnr -f '\\d' '1' ./*\n```\n*Original tree*\n```\n.\n├── file-01.txt\n├── file-02.txt\n└── file-03.txt\n```\n*Renamed tree*\n```\n.\n├── file-11.txt\n├── file-12.txt\n└── file-13.txt\n```\n#### Capture groups\n1. Capture three unnamed groups [`name(1)-number(2).extension(3)`].\n2. Swap group 1 (name) and group 2 (number).\n```sh\nrnr -f '(\\w+)-(\\d+).(\\w+)' '${2}-${1}.${3}' ./*\n```\n*Original tree*\n```\n.\n├── file-01.txt\n├── file-02.txt\n└── file-03.txt\n```\n*Renamed tree*\n```\n.\n├── 01-file.txt\n├── 02-file.txt\n└── 03-file.txt\n```\n__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.\n#### Capture several named groups and swap them\n1. Capture two digits as `number`.\n2. Capture extension as `ext`.\n3. Swap groups.\n```sh\nrnr -f '(?P\u003cnumber\u003e\\d{2})\\.(?P\u003cext\u003e\\w{3})' '${ext}.${number}' ./*\n```\n*Original tree*\n```\n.\n├── file-01.txt\n├── file-02.txt\n└── file-03.txt\n```\n*Renamed tree*\n```\n.\n├── file-txt.01\n├── file-txt.02\n└── file-txt.03\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fismaelgv%2Frnr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fismaelgv%2Frnr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fismaelgv%2Frnr/lists"}