File Naming Normalization
Normalize asset filenames: split → clean each segment → join with _ (snake_case).
Rules
When this skill applies, read and follow skill-dependency-manager — run scripts as documented, install missing tools into .dependency/.
Quick Start
Default: split on _, -, ., and spaces; strip leading/trailing digits from each segment; join with _:
.dependency/python/python .ai/file-naming-normalization/normalize.py path/to/file_or_folder
Preview without renaming:
.dependency/python/python .ai/file-naming-normalization/normalize.py Audio/SFX --dry-run
Workflow
- Split the filename stem (extension is preserved) on common separators:
_,-,., whitespace. - Clean each segment:
- Drop pure-digit segments with 4+ digits (asset IDs like
38126) - Keep short pure-digit segments as variant indices (
1,2,01) - Remove leading digits from mixed segments (
001Hero→Hero) - Remove trailing digits from mixed segments (
Attack02→Attack,foisal72→foisal) - Remove user-given strings (see
--strip)
- Drop pure-digit segments with 4+ digits (asset IDs like
- Drop empty segments after cleaning.
- Join remaining segments with
_. - Rename in place (or write to
--output-dir).
Examples
| Input | Output |
|---|---|
001_Hero_Attack_02.wav |
001_Hero_Attack_02.wav (already snake_case) |
001-Hero-Attack-02.wav |
001_Hero_Attack_02.wav |
sfx-button-click.mp3 |
sfx_button_click.mp3 |
UI 12 Panel Open.png |
UI_12_Panel_Open.png |
freesound_community-shoot-1-81135.wav |
freesound_community_shoot_1.wav |
SFX_001_button.wav with --strip SFX |
001_button.wav |
# Strip custom strings (repeatable)
.dependency/python/python .ai/file-naming-normalization/normalize.py Assets --strip SFX --strip UI
# Recursive folder
.dependency/python/python .ai/file-naming-normalization/normalize.py Assets -r
# Copy normalized files to another folder (originals unchanged)
.dependency/python/python .ai/file-naming-normalization/normalize.py Assets -o normalized/ -r
Output
--dry-run preview (unchanged files such as 001_Hero_Attack_02.wav are omitted):
Assets/001-Hero-Attack-02.wav -> Assets/001_Hero_Attack_02.wav
Assets/freesound_community-shoot-1-81135.wav -> Assets/freesound_community_shoot_1.wav
Assets/sfx-button-click.mp3 -> Assets/sfx_button_click.mp3
Assets/UI 12 Panel Open.png -> Assets/UI_12_Panel_Open.png
Dry run: 4 file(s) would be renamed.
In-place rename:
Assets/001-Hero-Attack-02.wav -> Assets/001_Hero_Attack_02.wav
Renamed 1 file(s).
Nothing to change:
All filenames already normalized.
With --strip SFX:
Assets/SFX_001_button.wav -> Assets/001_button.wav
Renamed 1 file(s).
Copy to --output-dir (originals kept):
Assets/SFX_001_button.wav -> normalized/001_button.wav
Renamed 1 file(s).
Name collision (exit code 1):
Name collision: 'Assets/Hero-Attack.wav' and 'Assets/Hero.Attack.wav' both map to 'Assets/Hero_Attack.wav'
Common Flags
-r / --recursive · --strip TEXT (repeatable) · --strip-case-insensitive · -o / --output-dir · --dry-run · --overwrite
Agent Notes
- Use the bundled script; do not hand-write rename loops unless the script cannot cover the case.
- Always run
--dry-runfirst when normalizing many files; show the user the preview. --stripremoves the given substring anywhere inside each segment (not only at edges). Pass one--stripper string.- Segments that become empty after cleaning are dropped (
81135alone → skipped). - Collisions (two files mapping to the same name) abort with an error — resolve manually or normalize in smaller batches.
- Only renames files; does not rename directories.
CLI
Copy-paste commands: cli/file-naming-normalization.md