# {[m]atch=[r]eplace:[f]ormat} [![crates.io](https://img.shields.io/crates/v/mrf)](https://crates.io/crates/mrf) [![License](https://img.shields.io/crates/l/mrf)](LICENSE.md) [![Tests Status](https://github.com/kerlilow/mrf/workflows/tests/badge.svg)](https://github.com/kerlilow/mrf/actions) mrf (pronounced "morph") lets you rename files by pattern matching. ## Demo ### Rename files ![Rename files demo](/demos/rename.svg?raw=true) ### Organize files ![Organize files demo](/demos/organize.svg?raw=true) ### Format numbers ![Format numbers demo](/demos/format.svg?raw=true) ## Installation ### On Linux You can install mrf with [Homebrew](https://brew.sh/): ``` brew tap kerlilow/tools brew install mrf ``` ### On macOS You can install mrf with [Homebrew](https://brew.sh/): ``` brew tap kerlilow/tools brew install mrf ``` ### From source You can install mrf from source using Rust's package manager [Cargo](https://github.com/rust-lang/cargo): ```sh $ cargo install mrf ``` ### From binaries The [release page](https://github.com/kerlilow/mrf/releases) includes precompiled binaries for Linux, macOS and Windows. ## How It Works ### Tokenization The input string is split into tokens. There are 4 types of tokens: 1. **Number** - A contiguous string of ASCII digits (0-9). 2. **Whitespace** - A contiguous string of ASCII whitespaces. 3. **Punctuation** - A contiguous string of ASCII punctuations. 4. **Text** - A contiguous string of characters that are none of the above. For example, the string `example-001` will be tokenized as `[example][-][001]`. ### Matching Each matcher matches one or more tokens. There are 2 types of matchers: 1. **Any** - Match any type of tokens, the default matcher. Example: `{}`. 2. **Number** - Match a Number token, specified with `n`. Example: `{n}`. Note: A matcher matches the minimum number of tokens required. For example, the string `example-001` with the replacer string `{}{n}` will be matched as: ``` [example-][001] ^^^^^^^^ ^^^ Any Number ``` Note that the Any matcher matches 2 tokens here. On the other hand, for the same string, if the replacer string `{}{}` will be matched as: ``` [example][-001] ^^^^^^^ ^^^^ Any Any ``` Note that this time, the first Any matcher matched the 1 token, while the second Any matcher matched 2 tokens. ### Replacing A replacement string may be specified to replace the matched substring with an equal sign (`=`) in the specifier. Example: `{=replaced}`. ### Formatting A format specifier may be specified to format the matched substring (or the replacement, if specified). The following format specifiers are supported: 1. **Padding** (aligned to the right) - Specify the desired width. Example: `{:3}`. 2. **Zero padding** (aligned to the right) - Specify `0`, followed by the desired width. Example: `{:03}`. ## Usage ### Rename/move files with `mrf mv` ``` mrf mv ... ``` #### Examples ##### Replace hyphen with underscore ```sh $ mrf mv * '{}{=_}{}' Moving 1 out of 1 items: image-001.jpg -> image_001.jpg ``` ##### Rename while keeping numbering ```sh $ mrf mv * '{=photo}{}' Moving 1 out of 1 items: image-001.jpg -> photo-001.jpg ``` ##### Add zero padding ```sh $ mrf mv * '{}{n:03}{}' Moving 1 out of 1 items: image-1.jpg -> image-001.jpg ``` ### Execute commands with `mrf exec` ``` mrf exec ... ``` #### Examples ##### Make directory ```sh $ mrf exec -r 'mkdir -p' * '{3}{=}' Matched 1 out of 1 items: image-2020-01-01.jpg -> 2020 ``` ##### Copy files ```sh $ mrf exec cp * '{}{=_}{}' Matched 1 out of 1 items: image-001.jpg -> image_001.jpg ``` ### Map strings with `mrf map` (useful for testing and understanding) ``` mrf map [FLAGS] ... ``` #### Examples ##### Replace hyphen with underscore ```sh $ mrf map example-001 '{}{=_}{}' example-001 -> example_001 ``` ##### Pipe to cp (consider using the "exec" subcommand instead) ```sh $ mrf map * '{}{=-}{}' | xargs -0 -n2 cp ``` ## Roadmap - [ ] Nicer error reports - [x] Match highlighting - [ ] More installation methods - [ ] Exact, prefix, suffix matcher - [ ] Regex matcher ## License This project is licensed under the terms of the MIT license. See the [LICENSE.md](LICENSE.md) file in this repository for more information.