A smart, fast CLI tool to batch normalize and clean filenames with Unicode support, case transformation, and intelligent conflict resolution.
- π Unicode Support β Converts accented characters and special letters to ASCII equivalents
- π§ Case Transformation β Lowercase, uppercase, or title case (optional, no forced defaults)
- π Date Prefixing β Add file modification date or current date as prefix (optional)
- β‘ Conflict Resolution β Automatically handles duplicate filenames with numeric suffixes (
_2,_3, etc.) - π Recursive Processing β Optionally process subdirectories with
-r - ποΈ Dry-Run Mode β Preview all changes before applying (default behavior)
- π JSON Output β Machine-readable results for automation and scripting
- π Fast & Safe β Handles thousands of files efficiently with proper error handling
git clone https://github.com/johndo100/cleanfy.git
cd cleanfy
go build -o cleanfyDownload prebuilt binaries from Releases
cleanfy ./photoscleanfy -x ./photoscleanfy -x -r --case=lower ./all_files| Flag | Long Form | Description |
|---|---|---|
-x |
--execute |
Execute renames (default: preview only) |
-r |
--recursive |
Recurse into subdirectories |
-q |
--quiet |
Suppress output (errors only) |
-j |
--json |
Output as JSON |
-v |
--version |
Show version and exit |
-a |
--dotfiles |
Include hidden files (starting with .) |
--case= |
--case= |
Case transform: lower, upper, title (optional) |
--date= |
--date= |
Date prefix: mtime (modified) or now (current) (optional) |
--date-format= |
--date-format= |
Go time layout (default: 2006-01-02) |
Note: All value flags must use the = form (e.g., --case=lower, --date=mtime)
# Preview changes
cleanfy ./photos
# Apply lowercase transformation to all files
cleanfy -x --case=lower ./photos
# Recursive processing with uppercase
cleanfy -x -r --case=upper ./documents
# Add current date prefix to files
cleanfy -x --date=now ./backup
# Add file modification date as prefix with custom format
cleanfy -x --date=mtime --date-format="20060102_150405" ./archive
# Recursive with date and custom case
cleanfy -x -r --case=title --date=mtime ./library
# Process including hidden files
cleanfy -x -a ./config
# JSON output for scripting
cleanfy -j ./files | jq '.[] | select(.renamed == true)'
# Quiet mode with errors only
cleanfy -x -q -r ./large_directory
# Custom date format examples
cleanfy --date=now --date-format="2006-01-02" ./files # 2025-11-12
cleanfy --date=now --date-format="Jan 2 2006" ./files # Nov 12 2025
cleanfy --date=now --date-format="20060102_150405" ./files # 20251112_165030- Accents β
cafΓ©βcafe,ZΓΌrichβZurich - Special Ligatures β
straΓeβstrasse,ΓtherβAEther - Strokes β
ΕΓ³dΕΊβLodz,ΔΓ mβdam - Quotes & Dashes β Smart handling of curly quotes, en-dashes, em-dashes
- Spaces & Punctuation β Converted to underscores:
My File!βmy_file - Multiple Separators β Collapsed:
file___nameβfile_name - Leading/Trailing β Trimmed:
.file_βfile - Reserved Names β Windows reserved names prefixed with
_:COMβ_com - Length β Safely truncated while preserving UTF-8 validity
- Case β Lower, upper, or title case (opt-in via
--case=) - Date Prefix β Add mtime or current date (opt-in via
--date=)
- Duplicates β Auto-resolved with numeric suffixes:
file.txtβfile_2.txt - Always On β Prevents overwrites automatically
RENAME MyFile.txt -> myfile.txt
OK already_clean.txt
RENAME* Duplicate.pdf -> duplicate_2.pdf (auto-resolved)
ERR Protected.txt : permission denied
RENAME MyFile.txt -> myfile.txt
RENAME* Duplicate.pdf -> duplicate_2.pdf (auto-resolved)
[
{
"path": "/path/to/myfile.txt",
"old_name": "MyFile.txt",
"new_name": "myfile.txt",
"is_dir": false,
"renamed": true,
"auto_renamed": false,
"skipped": false,
"error": ""
}
]Run the full test suite:
# Verbose output
go test ./... -v
# With coverage report
go test ./... -cover
# Run benchmarks
go test -bench=. ./...Current Coverage: 34.5% with 100+ test cases across core functions
- Single directory (100 files): ~50ms
- Recursive (1000 files): ~200ms
- Large batch (10,000 files): ~2s
β
Dry-run by default β Use -x to apply changes
β
Dotfiles skipped by default β Use -a to process hidden files
β
No forced transformations β Case/date are optional
β
Automatic conflict resolution β Prevents overwrites
β
Error reporting β Clear feedback on failures
- β Linux
- β macOS (Intel & Apple Silicon)
- β Windows
Current version is automatically detected from git tags and build metadata.
cleanfy -v
# cleanfy v0.9.0-pre (linux/amd64)This project uses GitHub Actions for:
- β Automated testing on push/PR
- β Cross-platform builds on tag
- β Automatic release creation
See CI_RELEASE_GUIDE.md for details.
See LICENSE file for details
Found a bug or have a feature request?
Please open an issue on GitHub
Made with β€οΈ for batch file normalization