| Crates.io | ftmi |
| lib.rs | ftmi |
| version | 0.2.8 |
| created_at | 2025-09-14 21:32:57.467593+00 |
| updated_at | 2025-09-15 00:08:16.84365+00 |
| description | A Rust-based file renaming utility |
| homepage | |
| repository | https://github.com/ben-haware/FTMI |
| max_upload_size | |
| id | 1839160 |
| size | 145,395 |
FTMI is a Rust-based file renaming utility that intelligently detects and removes file prefixes. Built for efficiency with SQLite-powered undo capabilities and interactive workflows.
# Quick install (handles all dependencies)
git clone https://github.com/ben-haware/FTMI && cd FTMI && make install
# Interactive prefix removal (main functionality)
ftmi rename ./music
# Continuous mode for multiple directories
ftmi rename --continuous
# Undo the last operation
ftmi rename --undo
[Artist], (Draft), IMG_*rename --undo restores the most recent operationrename --list shows all recent operationsrename --undo <operation_id> for specific operations[Artist] Song.mp3 → Song.mp3(Draft) Document.pdf → Document.pdf--regex for any patternftmi rename ./music
🔧 FTMI Interactive Prefix Removal Tool
📁 Directory: ./music
Found 1 prefix group(s) with highest occurrence count:
🏷️ Prefix 1: [Dua Lipa]
Files (3):
[Dua Lipa] Levitating.mp3 → Levitating.mp3
[Dua Lipa] Don't Start Now.mp3 → Don't Start Now.mp3
[Dua Lipa] Physical.mp3 → Physical.mp3
💡 Remove prefix [Dua Lipa] from these 3 files? (Y/n/s=skip, default=Y): y
✅ Proceeding with prefix removal...
🔄 Renaming: [Dua Lipa] Levitating.mp3 → Levitating.mp3
✓ Success!
📊 Results: 3 successful, 0 failed
💾 Operation ID: op_1757889353 (use this to undo if needed)
ftmi rename --continuous
🔄 Continuous mode started. Paste directory paths and press Enter.
💡 Each path will be processed immediately after a brief delay.
Press Ctrl+C to exit.
# Paste: /Users/me/Music/Rock /Users/me/Music/Pop /Users/me/Music/Jazz
📂 Processing 3 directories (pasted together):
1: /Users/me/Music/Rock
2: /Users/me/Music/Pop
3: /Users/me/Music/Jazz
🔍 Processing directory 1 of 3: /Users/me/Music/Rock
[Interactive processing for each directory...]
# Undo the most recent operation
ftmi rename --undo
🔄 Finding most recent operation to undo...
🎯 Most recent operation: op_1757889353
🔄 Undoing operation: op_1757889353
📂 Directory: /Users/me/music
🏷️ Prefix: [Dua Lipa]
📅 Original timestamp: 2025-09-14 22:35:53 UTC
📊 Files to restore: 3
🔄 Preview of restore operation:
Levitating.mp3 → [Dua Lipa] Levitating.mp3
Don't Start Now.mp3 → [Dua Lipa] Don't Start Now.mp3
Physical.mp3 → [Dua Lipa] Physical.mp3
💡 Are you sure you want to undo this operation? (y/N): y
✅ Proceeding with undo...
📊 Undo results: 3 successful, 0 failed
✅ Operation successfully undone!
ftmi rename --list
📋 Recent rename operations:
1. Operation ID: op_1757889353
Timestamp: 2025-09-14 22:35:53 UTC
Directory: /Users/me/music
Prefix removed: [Dua Lipa]
Files renamed: 3
[Dua Lipa] Levitating.mp3 → Levitating.mp3
[Dua Lipa] Don't Start Now.mp3 → Don't Start Now.mp3
[Dua Lipa] Physical.mp3 → Physical.mp3
💡 Use 'rename --undo <operation_id>' to undo any operation.
# Remove parentheses-delimited prefixes
ftmi rename --regex '\(.*\)' ./documents
# Remove any prefixes (no filtering)
ftmi rename --no-filter ./mixed_files
# Process multiple directories
ftmi rename ./music ./photos ./documents
git clone https://github.com/ben-haware/FTMI && cd FTMI && make install
This automatically installs Rust, cargo-binstall, and FTMI
Using cargo-binstall (fastest if you have Rust):
cargo binstall ftmi
From source:
cargo install ftmi
Manual build:
git clone https://github.com/ben-haware/FTMI
cd FTMI
cargo build --release
ftmi renameftmi rename [OPTIONS] [DIRECTORIES...]
OPTIONS:
-r, --regex PATTERN Use custom regex to filter prefixes (default: \[.*\])
--no-filter Accept all prefixes (no regex filtering)
-c, --continuous Continuous mode: listen for pasted paths
-u, --undo [ID] Undo an operation (most recent if no ID given)
-l, --list List recent rename operations
-h, --help Show help message
EXAMPLES:
ftmi rename ./music # Interactive rename with preview
ftmi rename --continuous # Continuous mode for multiple dirs
ftmi rename --undo # Undo most recent operation
ftmi rename --list # Show operation history
ftmi rename --regex '\(.*\)' ./docs # Custom pattern matching
ftmi # Find longest prefixes (analysis only)
echo "./music" | ftmi # Pipe directory paths for analysis
# Command line + piped input
echo "./photos" | ftmi rename ./music ./documents
# Bracket prefixes: [Artist] Song.mp3
ftmi rename ./music
# Parentheses prefixes: (Draft) Document.pdf
ftmi rename --regex '\(.*\)' ./documents
# Image prefixes: IMG_001.jpg, DSC_002.jpg
ftmi rename --regex 'IMG_.*|DSC_.*' ./photos
# No filtering (show all prefixes)
ftmi rename --no-filter ./mixed_files
# Process multiple music directories in sequence
find ~/Music -maxdepth 1 -type d | ftmi rename --continuous
# Quick undo if something goes wrong
ftmi rename --undo
Use FTMI as a library in your Rust projects:
use ftmi::{find_longest_prefix, PrefixOptions, PrefixedPath, RenameDatabase, tracked_rename};
// Find prefixes
let options = PrefixOptions::default();
let results: Vec<PrefixedPath> = find_longest_prefix(Path::new("/music"), &options)?;
// Track renames with database
let db = RenameDatabase::new(db_path);
db.initialize()?;
let operation_id = generate_operation_id();
tracked_rename(&db, &old_path, &new_path, &prefix, &operation_id)?;
Main Tool:
ftmi - Main CLI with subcommands
ftmi rename - Interactive prefix removal tool (primary)ftmi (default) - Prefix analysis and detectionDatabase:
~/.ftmi/renames.dbContributions welcome! Please submit pull requests or open issues.
Free for individual use. Commercial license required for corporations. See LICENSE for details.