Skip to main content

PyPI version Downloads License GitHub stars CI

renux

A terminal-based bulk file renamer with a TUI

Preview

About

renux is a tool with a text-based (terminal) user interface (TUI) that automates file renaming. It simplifies this task with features like regex, placeholders, and text transformations, making it ideal for situations such as renaming photos, cleaning up download folders, or enforcing consistent naming conventions.

Features

  • Regex: perform advanced renaming with pattern matching, capturing groups, and replacements.
  • Text transformations: apply text transformations like slugify, camelCase to snake_case, and more.
  • Counter placeholders: add incremental counters (e.g., file1.txt, file2.txt) with customizable starting points, increments, and padding.
  • Date placeholders: include file creation/modification dates or the current date in filenames with customizable formats.
  • File size placeholders: include a file's size, auto-scaled to the largest sensible unit or a specific one (bytes, KB, MB, GB).
  • Image placeholders: include an image's width and height in pixels, plus EXIF capture date and camera make/model when available.
  • Location placeholders: include a photo's GPS latitude, longitude, and altitude from EXIF data when available.
  • Video placeholders: include a video's width, height, frame rate, and duration.
  • Backup and undo/redo: save and restore changes to your files.
  • File exclusion: exclude files from renaming.
  • Keyboard shortcuts: use hotkeys to quickly apply actions and navigate the UI.

Installation

Using pipx (recommended).

pipx install renux

Alternatively, you can use pip.

AI Agent Skill

If you use an AI coding agent (Claude Code, etc.), you can install a skill that teaches it how to drive renux for bulk-renaming tasks:

npx skills add https://github.com/andrianllmm/renux/tree/main/skills/renux

Usage

renux [directory] [pattern] [replacement]

Arguments

  • directory: Directory where files are located (default is the current directory or .).
  • pattern: Search pattern, which can be a regular expression (default is '').
  • replacement: Replacement string for the pattern (default is '').

Options

  • -c COUNT, --count COUNT: Max replacements per file (default is 0, meaning unlimited).
  • -r, --regex: Treats the pattern as a regular expression (default is True).
  • --case-sensitive: Makes the search case-sensitive (default is False).
  • --apply-to: Specifies where the renaming should be applied. Options are:
  • name: Rename the file's base name (default).
  • ext: Rename the file's extension.
  • both: Rename both the name and extension.
  • --exclude PATTERN: Exclude files matching PATTERN (exact name or glob, e.g. README.md, *.log). Repeatable, e.g. --exclude README.md --exclude Dockerfile. In the TUI, this is a comma-separated field in the form.

Patterns are evaluated in order, gitignore-style: prefix a pattern with ! to re-include a file matched by an earlier pattern, e.g. --exclude "*.txt" --exclude "!foo1.txt" excludes all .txt files except foo1.txt.

  • -y, --yes: Apply the rename immediately without opening the TUI (headless mode, useful for scripts/CI).
  • --dry-run: Preview the rename without opening the TUI or changing any files (headless mode).
  • --undo: Undo the last rename applied to directory without opening the TUI (headless mode).
  • --redo: Redo the last undone rename in directory without opening the TUI (headless mode).

Tags

  • Text transformations: {string|filter}

    • slugify: Convert into a URL/filename-friendly format (e.g. "hello world" → "hello-world")
    • lower: Convert to lowercase
    • upper: Convert to uppercase
    • caps: Capitalize the first letter
    • title: Capitalize each word
    • camel: Convert to camel case (e.g. "hello world" → "helloWorld")
    • pascal: Convert to pascal case (e.g. "hello world" → "HelloWorld")
    • snake: Convert to snake case (e.g. "hello world" → "hello_world")
    • kebab: Convert to kebab case (e.g. "hello world" → "hello-world")
    • swapcase: Swap the case (e.g. "Hello World" → "hELLO wORLD")
    • reverse: Reverse the string (e.g. "Hello World" → "dlroW olleH")
    • strip: Remove leading and trailing whitespace
    • len: Get the length of the string
  • General

    • Counter: {counter(start=1,step=1,padding=1)}, e.g., {counter(1,2,3)} Insert an incrementing counter. Each placeholder occurrence tracks its own sequence, advancing by step after every file.
  • Date

    • Now: {now(<format>)}, e.g., {now(%Y)} The current date/time.
    • Created At: {created_at(<format>)} The file's creation date/time.
    • Modified At: {modified_at(<format>)} The file's last-modified date/time.
  • File

    • Size: {size(<unit>)}, e.g., {size(mb)} The file's size. Auto-scaled to the largest sensible unit unless a unit (b, kb, mb, gb) is given.
  • Image

    • Width: {width} The image's width in pixels.
    • Height: {height} The image's height in pixels.
    • Taken At: {taken_at(<format>)}, e.g., {taken_at(%Y)} The photo's capture date/time from EXIF metadata. Not available for images without EXIF data (e.g. screenshots, re-exported/edited images).
    • Camera Make: {camera_make} The camera manufacturer from EXIF metadata. Not available for images without EXIF data.
    • Camera Model: {camera_model} The camera model from EXIF metadata. Not available for images without EXIF data.
  • Location

    • Latitude: {latitude} The photo's GPS latitude in decimal degrees. Not available for images without GPS EXIF data.
    • Longitude: {longitude} The photo's GPS longitude in decimal degrees. Not available for images without GPS EXIF data.
    • Altitude: {altitude} The photo's GPS altitude in meters. Not available for images without GPS EXIF data.
  • Video

    • Video Width: {video_width} The video's width in pixels.
    • Video Height: {video_height} The video's height in pixels.
    • Frame Rate: {frame_rate} The video's frame rate. Not available for all containers (e.g. MP4).
    • Duration: {duration} The video's duration, in seconds.

Run renux --help for more details.

Examples

  • Rename files starting with "IMG" to "Image":
    renux my_photos/ IMG_ Image_
    
  • Rename all .txt files to .bak:
    renux my_directory/ .txt .bak --apply-to ext
    
  • Use regex to retain information from the old name:
    renux my_documents "document (\d).pdf" "doc (\1).pdf" -r
    
  • Append a counter to filenames:
    renux my_files/ file "file_{counter}"
    
  • Append creation year to filenames:
    renux my_files/ file "file_{created_at(%Y)}"
    
  • Apply transformations like slugify:
    renux my_files "(.*)" "{filename|slugify}" -r
    

Dev Setup

  1. Clone the repo
    git clone https://github.com/andrianllmm/renux.git
    cd renux
    
  2. Install dependencies with Poetry
    poetry install
    

Testing

Run tests with pytest:

poetry run python -m pytest

Contributing

Contributions are welcome! See CONTRIBUTING.md for more details.

License

Distributed under the MIT License.

Metadata

Release files for renux 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for renux 0.4.1
File Size Uploaded
renux-0.4.1.tar.gz 23.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for renux 0.4.1
File Interpreter ABI Platform
renux-0.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 50.8 kB

Release files / renux-0.4.1.tar.gz

Download URL renux-0.4.1.tar.gz
Size 23.5 kB
Tags Source
SHA-256 checksum
How to use checksums
29ff8ed954ddf5179aaa7643e792f43be3348c9568c2da04eef3fd966b70785b
BLAKE2b-256 checksum
How to use checksums
9c63b9b16591c64a0858ac1512ac4cfa32abbdf382b6e1dc616829f165dbe694
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.

Transparency log

Release files / renux-0.4.1-py3-none-any.whl

Download URL renux-0.4.1-py3-none-any.whl
Size 27.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e8458756baa6ae72f25938123fc52463241ed1c6f82af7d1eed5525e5106270e
BLAKE2b-256 checksum
How to use checksums
3f5193c552a71da5ed0ae9a2b7f2eaf9a811cd6646bf067cd3b729a09de632a3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page