Generate a Safe Rename Script
Paste your old → new filename mapping and get a quoted, correctly ordered bash or PowerShell rename script — with the undo script beside it. Nothing moves until you run it.
About this tool
You already know what the files should be called — the risky part is writing the script that does it. Paste the old,new mapping and this tool emits the rename script for you, quoted correctly, ordered so nothing gets clobbered, and paired with an undo script. It runs entirely in your browser and never touches a file: the output is text you review, save, and run yourself.
Each line is one pair. Comma, tab, |, and -> all work, and auto-detect picks the one that fits every line. Blank lines and # comments are ignored, and a header row such as old,new is skipped.
Worked example — this mapping:
IMG_001.JPG,photo-001.jpg
IMG_002.JPG,photo-002.jpg
produces this rename script (with the undo option off, for brevity):
#!/usr/bin/env bash
# Rename script generated by mv-script-generator — 2 renames.
# Review this script before running it. Nothing moves until you run it.
set -euo pipefail
mv_safe() {
local src=$1 dst=$2
if [ ! -e "$src" ] && [ ! -L "$src" ]; then
printf 'mv-script: missing source: %s\n' "$src" >&2
exit 1
fi
if [ -e "$dst" ] || [ -L "$dst" ]; then
printf 'mv-script: destination exists: %s\n' "$dst" >&2
exit 1
fi
mkdir -p -- "$(dirname -- "$dst")"
mv -- "$src" "$dst"
}
mv_safe 'IMG_001.JPG' 'photo-001.jpg'
mv_safe 'IMG_002.JPG' 'photo-002.jpg'
What the generator does that a hand-written loop usually doesn't
- Ordering. A chained mapping (
a → b,b → c) is sorted sob → cruns first. Written in the order you typed it,a → bwould destroybbefore it was ever moved. - Cycles. A straight swap (
a → b,b → a) can't be ordered at all, so one side is staged through a.mvtmp1temp name and finished at the end — and the undo script unwinds through the same temp name. - Quoting. Every path is single-quoted with dialect-correct escaping (
'\''for POSIX, doubled''for PowerShell) and passed aftermv --or via-LiteralPath, so spaces, apostrophes,$HOME, and leading dashes are all inert. - Collision checks. Two lines renaming the same file, or two lines producing the same new name, are refused up front with both line numbers — before a script exists that could destroy something.
- Guards at run time. The emitted helper aborts on a missing source, and (unless you allow overwriting) on a destination that already exists.
Options
- Script dialect — bash writes
set -euo pipefailplus anmv_safehelper; PowerShell writes$ErrorActionPreference = 'Stop'plus aMove-Safehelper that usesRename-Item -LiteralPathfor same-directory renames andMove-Itemwhen the destination changes folder. - Dry run — bash prints
would move: old -> newfor each pair; PowerShell passes the-WhatIfswitch. - Run in this directory — prepends a quoted
cd --/Set-Location -LiteralPathso your mapping can use bare filenames. - Create missing destination directories — on by default, so
a.txt -> 2026/01/a.txtworks. - Undo script — on by default; you get the reverse script under a second header in the same output.
Limits and edge cases
- Up to 1000 rename pairs per run.
- A pair whose old and new name are identical is skipped and counted in the header comment; if every pair is like that, you get an error instead of an empty script.
- Filenames containing control characters are refused — they cannot be written safely into a script.
- The tool assumes each old name exists and each new name does not. It cannot check that, so the emitted script checks at run time and stops on the first problem.
- Nothing is executed here. Read the script before you run it, and prefer a dry run on the real directory first.
FAQ
Does this tool rename my files?
No. It runs in your browser and only produces text. You copy or download the script, read it, and run it yourself in the directory you choose.
How do I get an old,new mapping in the first place?
Any two-column list works — a spreadsheet export, ls piped into a text editor, or the sibling bulk file renamer tool, which derives new names from find/replace, regex, numbering, or case rules and prints exactly the old -> new list this tool consumes.
What happens if two files need to swap names?
The generator detects the cycle and stages one file through a temp name: a.txt → a.txt.mvtmp1, then b.txt → a.txt, then a.txt.mvtmp1 → b.txt. The undo script reverses the same three steps, so a swap is fully reversible.
My filenames contain commas. Will the CSV split break them?
Choose the CSV format and wrap the field in double quotes — "report, final.txt",report-final.txt — or switch to the tab, pipe, or arrow format instead. Auto-detect also skips a separator that doesn't split every line cleanly.
Why does the script refuse to overwrite an existing file?
Because an overwrite in a bulk rename is almost always a mistake that costs you a file. The default helper stops with destination exists: <name>. If replacing is what you want, tick the overwrite option and the script switches to mv -f / -Force.
Can I use absolute paths, or move files between folders?
Yes. A pair like /tmp/in/a.txt,/srv/archive/2026/a.txt is fine, and so is a relative destination in a subfolder. With "create missing destination directories" on, the parent folders are created first; the PowerShell script switches from Rename-Item to Move-Item automatically when the destination folder differs.
Developer & Automation Access
Run it from the terminal
Same engine as this page, headless — via the gizza CLI:
gizza tool mv-script-generator "IMG_001.JPG,photo-001.jpg
IMG_002.JPG,photo-002.jpg"New to the CLI? Get gizza →
Open it by URL
Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:
https://gizza.ai/tools/mv-script-generator/?mapping=IMG_001.JPG%2Cphoto-001.jpg%0AIMG_002.JPG%2Cphoto-002.jpg&format=auto&shell=bash&base_dir=%2Fhome%2Fme%2Fphotos&dry_run=true&overwrite=true&mkdir_parents=true&undo_script=true&comments=trueMachine-readable descriptor: tool.json — title + parameters JSON Schema for agents.
