{"id":21071490,"url":"https://github.com/igrek51/regex-rename","last_synced_at":"2025-05-16T05:31:31.126Z","repository":{"id":41987724,"uuid":"84882071","full_name":"igrek51/regex-rename","owner":"igrek51","description":"Bulk rename tool based on regular expressions to rename multiple files at once","archived":false,"fork":false,"pushed_at":"2024-09-23T13:31:57.000Z","size":995,"stargazers_count":24,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-19T20:44:11.352Z","etag":null,"topics":["bulk","regex","regular-expression","rename","rename-files"],"latest_commit_sha":null,"homepage":"https://igrek51.github.io/regex-rename/","language":"Python","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/igrek51.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2017-03-13T22:50:48.000Z","updated_at":"2025-04-13T23:24:28.000Z","dependencies_parsed_at":"2024-02-19T13:00:52.136Z","dependency_job_id":"b8d90541-405a-4edd-ad13-486260f601eb","html_url":"https://github.com/igrek51/regex-rename","commit_stats":{"total_commits":23,"total_committers":3,"mean_commits":7.666666666666667,"dds":0.08695652173913049,"last_synced_commit":"25031a26dac7eda3696732ef0ff9b256361a49df"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igrek51%2Fregex-rename","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igrek51%2Fregex-rename/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igrek51%2Fregex-rename/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igrek51%2Fregex-rename/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/igrek51","download_url":"https://codeload.github.com/igrek51/regex-rename/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254474162,"owners_count":22077230,"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":["bulk","regex","regular-expression","rename","rename-files"],"created_at":"2024-11-19T18:53:22.708Z","updated_at":"2025-05-16T05:31:26.105Z","avatar_url":"https://github.com/igrek51.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# regex-rename\n\n[![GitHub version (latest SemVer)](https://img.shields.io/github/v/tag/igrek51/regex-rename?label=github\u0026sort=semver)](https://github.com/igrek51/regex-rename)\n[![PyPI](https://img.shields.io/pypi/v/regex-rename)](https://pypi.org/project/regex-rename)\n[![Github Pages](https://img.shields.io/badge/docs-github.io-blue)](https://igrek51.github.io/regex-rename)\n[![codecov](https://codecov.io/gh/igrek51/regex-rename/branch/master/graph/badge.svg)](https://codecov.io/gh/igrek51/regex-rename)\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/igrek51/regex-rename/test.yml?branch=master\u0026label=tests)](https://github.com/igrek51/regex-rename/actions?query=workflow%3Atest)\n\nBulk rename tool based on regular expressions to rename multiple files at once.\n\n\u003cdiv align=\"center\"\u003e\n    \u003ca href=\"https://github.com/igrek51/regex-rename\"\u003eGitHub\u003c/a\u003e\n    -\n    \u003ca href=\"https://pypi.org/project/regex-rename\"\u003ePyPI\u003c/a\u003e\n    -\n    \u003ca href=\"https://igrek51.github.io/regex-rename\"\u003eDocumentation\u003c/a\u003e\n\u003c/div\u003e\n\n## Quickstart\nRenaming multiple files at once:\n```shell\n$ ls # awful names:\nb45XDS-01.mp3  QsEW2s-02.mp3  VF7t6L-03.mp3\n\n$ regex-rename '-(\\d+).mp3' '\\1_NeverGonnaGiveYouUp.mp3' --rename\n[2022-04-09 09:19:15] DEBUG matching regular expression pattern to files: pattern=-(\\d+).mp3 replacement=\\1_NeverGonnaGiveYouUp.mp3 full_match=False dry_run=False\n[2022-04-09 09:19:15] INFO  renaming file: from=b45XDS-01.mp3 to=01_NeverGonnaGiveYouUp.mp3\n[2022-04-09 09:19:15] INFO  renaming file: from=QsEW2s-02.mp3 to=02_NeverGonnaGiveYouUp.mp3\n[2022-04-09 09:19:15] INFO  renaming file: from=VF7t6L-03.mp3 to=03_NeverGonnaGiveYouUp.mp3\n[2022-04-09 09:19:15] INFO  files renamed: renamed=3 mismatched=0\n\n$ ls # now we're talking:\n01_NeverGonnaGiveYouUp.mp3  02_NeverGonnaGiveYouUp.mp3  03_NeverGonnaGiveYouUp.mp3\n```\n\n## Installation\n```shell\npip3 install regex-rename\n```\n\nIt requires Python 3.7 (or newer) with pip.\n\n## Tutorial\n\nImagine you have 51 audio files with hideous names like this and you wish to rename them:\n\n- `Stanislaw+Lem+Invincible+(01).mp3` -\u003e `01 The Invincible.mp3`\n- `Stanis▯aw+Lem+Invincible+(02 ).mp3` -\u003e `02 The Invincible.mp3`\n- `Stanisław_Lem_Invincible (03) .mp3` -\u003e `03 The Invincible.mp3`\n- …\n- `Stanis▯aw+Lem+Invincible+(51).mp3` -\u003e `51 The Invincible.mp3`\n\nSpecifically, you want to place the episode number at the beginning.\n\n### Step 1: Match \n\nRegular Expressions can be tricky.\nWe figured out this pattern may match the files and extracts the episode number:\n```regexp\n(\\d+).*mp3\n``` \n\nFirst, let's check this pattern in a dry run: `regex-rename '(\\d+).*mp3'`  \n![Usage example](https://github.com/igrek51/regex-rename/blob/master/docs/img/screen-1.png?raw=true)\n\nPay attention to the extracted regex groups.\n\n### Step 2: Replace\n\nNow, we'd like to replace all files to a pattern: \n```regexp\n\\1 The Invincible.mp3\n``` \n`\\1` is a first group extracted by the matching pattern (episode number).\n\nLet's test it by adding the replacement pattern: `regex-rename '(\\d+).*mp3' '\\1 The Invincible.mp3'`  \n![Usage example](https://github.com/igrek51/regex-rename/blob/master/docs/img/screen-2.png?raw=true)  \n\n### Step 3: Execute\n\nAll above commands were just dry-run so that we could experiment with regex patterns.\nOnce we're sure that everything is matched correctly, we can append `--rename` flag, \nwhich does the actual renaming:  \n`regex-rename '(\\d+).*mp3' '\\1 The Invincible.mp3' --rename`  \n![Usage example](https://github.com/igrek51/regex-rename/blob/master/docs/img/screen-3.png?raw=true)  \n\nFinally, files are named properly:\n\n- `01 The Invincible.mp3`\n- `02 The Invincible.mp3`\n- `03 The Invincible.mp3`\n- …\n- `51 The Invincible.mp3`\n\n## Beyond the Regex\n`regex-rename` also supports some transformations not covered by regular expressions standard:\n\n- Converting to lowercase by adding `\\L` before group number:  \n`regex-rename '([A-Z]+).mp3' '\\L\\1.mp3'`  \neg. `AUDIO.mp3` to `audio.mp3`\n- Converting to uppercase by adding `\\U` before group number:  \n`regex-rename '([a-z]+).mp3' '\\U\\1.mp3'`  \neg. `audio.mp3` to `AUDIO.mp3`\n- Padding numbers with leading zeros by adding `\\P2`, `\\P3`, … (depending on padding length) before group number:  \n`regex-rename '(\\d+).mp3' '\\P2\\1.mp3'`  \neg. `1.mp3` to `01.mp3`\n- Padding numbers with leading zeros by specifying `--pad-to` parameter:  \n`regex-rename '(\\d+).mp3' '\\1.mp3' --pad-to=2`  \neg. `1.mp3` to `01.mp3`\n\n## More examples\n\n- Extract season and episode numbers, eg. `episode-02x05.mkv` to `S02E05.mkv`:  \n  ```shell\n  regex-rename '(\\d+)x(\\d+)' 'S\\1E\\2.mkv' --rename\n  ```\n  \n- Swap artist with title, eg. `Echoes - Pink Floyd.mp3` to `Pink Floyd - Echoes.mp3`:  \n  ```shell\n  regex-rename '([^-]+) - ([^-]+)\\.mp3' '\\2 - \\1.mp3' --rename\n  ```\n  \n- Pad leading zeros, eg. `1.mp3` to `001.mp3`:  \n  ```shell\n  regex-rename '(\\d+).mp3' '\\P3\\1.mp3' --rename\n  ```\n  \n- Convert to lowercase, eg. `SONG.MP3` to `song.mp3`:  \n  ```shell\n  regex-rename '(.+)' '\\L\\1' --rename\n  ```\n  \n- Convert to uppercase, eg. `Tool.mp3` to `TOOL.mp3`:  \n  ```shell\n  regex-rename '(.+)\\.mp3' '\\U\\1.mp3' --rename\n  ```\n  \n- Add prefix, eg. `Doors.mp3` to `The Doors.mp3`:  \n  ```shell\n  regex-rename '(.+)' 'The \\1' --full --rename\n  ```\n  \n- Change extension, eg. `Songbook.apk` to `Songbook.zip`:  \n  ```shell\n  regex-rename '(.+)\\.apk' '\\1.zip' --rename\n  ```\n  \n- Turn directories into prefixes and move files, eg. `Pink Floyd/Echoes.mp3` to `Pink Floyd - Echoes.mp3`:  \n  ```shell\n  regex-rename '(.+)/(.+).mp3' '\\1 - \\2.mp3' --full --recursive --rename\n  ```\n  \n- Rename files in different directories, preserving their parent directories,\n  eg. `app/logs/file-001.log` to `app/logs/file_001.txt`:  \n  ```shell\n  regex-rename '(.*)/file-([0-9]+).log' '\\1/file_\\2.txt' --full --recursive --rename\n  ```\n\n- Rename files piped from another command like `find`,\n  eg. `songs/Jimmi - Voodoo Child.mp3` to `songs/Jimi - Voodoo Child.mp3`:  \n  ```shell\n  find -iname '*jimmi*' | regex-rename '(.*)/.* - (.*).mp3$' '\\1/Jimi - \\2.mp3' --rename\n  ```\n\n\n## Usage\nEnter `regex-rename` for help:\n\n```shell\n$ regex-rename \nregex-rename v1.3.0 - Bulk rename tool based on regular expressions to rename multiple files at once\n\nUsage:\nregex-rename [OPTIONS] PATTERN [REPLACEMENT]\n\nArguments:\n   PATTERN       - Regex pattern to match filenames\n   [REPLACEMENT] - Replacement regex pattern for renamed files. Use \\1, \\2 syntax to make use of matched groups\n\nOptions:\n  --version                   - Print version information and exit\n  -h, --help [SUBCOMMANDS...] - Display this help and exit\n  -r, --rename                - Does actual renaming files instead of just testing replacement pattern\n  --full                      - Enforces matching full filename against pattern\n  --recursive                 - Search directories recursively\n  --collate                   - Compare source filenames with the replaced names\n  --short                     - Print output in short, less verbose format without time\n  --pad-to PAD_TO             - Applies padding with zeros with given length on matched numerical groups\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figrek51%2Fregex-rename","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Figrek51%2Fregex-rename","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figrek51%2Fregex-rename/lists"}