How to bulk rename files safely on Windows, macOS and Linux A developer published a hands-on guide to bulk renaming files safely on Windows, macOS and Linux, covering built-in tools like File Explorer, Finder, PowerShell and the shell, plus Microsoft's free PowerToys PowerRename. The guide warns that naive renumbering loops can silently overwrite files on Linux and macOS, and recommends two-phase renames, case-insensitive collision checks and dry-run previews. It also introduces TidyBatch, a free open-source command-line tool the author built around those rules, which previews by default and keeps a journal for one-command undo. Renaming hundreds of files takes seconds. Undoing a bad rename can be impossible. Here is how to do it on Windows, macOS and Linux without losing anything, with the free built-in options first. Disclosure: this article was written with AI help Claude , and every command below was run before publishing; the output shown is real. We make TidyBatch, a free command-line tool mentioned at the end, which has a paid Pro version 9 € . File Explorer. Select the files, press F2, type a name and press Enter. Windows names them Name 1 , Name 2 , … Fine for quick numbering, but no preview and no patterns. PowerToys PowerRename free, from Microsoft . Install Microsoft PowerToys https://learn.microsoft.com/en-us/windows/powertoys/powerrename , select files, right-click, Rename with PowerRename . Live preview, regular expressions, numbering and date variables. Ctrl+Z in Explorer undoes the batch right afterwards. PowerShell. Add -WhatIf to preview: Preview: lowercase all .jpg names and replace spaces with underscores Get-ChildItem -File .jpg | Rename-Item -NewName { $ .Name.ToLower -replace ' ', ' ' } -WhatIf Looks right? Run the same line without -WhatIf Get-ChildItem -File .jpg | Rename-Item -NewName { $ .Name.ToLower -replace ' ', ' ' } With two files, Holiday Photo.JPG and Beach Day.JPG , the -WhatIf line prints: What if: Performing the operation "Rename File" on target "Item: …/Beach Day.JPG Destination: …/beach day.jpg". What if: Performing the operation "Rename File" on target "Item: …/Holiday Photo.JPG Destination: …/holiday photo.jpg". Rename-Item refuses to replace an existing file Rename-Item: The file '…/a b.jpg' already exists. . Good, but in a long batch a few files fail halfway through, so read the red errors. Finder. Select the files, right-click, Rename… . Replace Text , Add Text or Format with a counter, with an example of the result. Edit → Undo straight away if it is wrong. Terminal. Use mv -n no-clobber and print the commands before you run them: Preview echo only , then remove "echo" to run for f in .JPG; do echo mv -n -- "$f" "${f%.JPG}.jpg"; done mv -n -- IMG 1.JPG IMG 1.jpg mv -n -- Photo One.JPG Photo One.jpg There are two different rename commands Perl and util-linux with different syntax. Run rename --version to see which you have. The util-linux one only prints the plan with -v : php Perl rename Debian/Ubuntu "rename" package : spaces - underscores rename -n 's/ / /g' rename My Trip 2.jpg, My Trip 2.jpg rename Photo One.jpg, Photo One.jpg util-linux rename Arch, Fedora… : replace the first "IMG " with "photo " rename -nv IMG photo IMG 1.JPG' - photo 1.JPG' Say you renumber 1.txt, 2.txt, 3.txt to 2.txt, 3.txt, 4.txt . A simple loop renames 1.txt → 2.txt first. On Linux and macOS a plain mv or Python's os.rename overwrites the original 2.txt without warning . On Windows it fails instead, leaving the folder half renamed. The fix is two phases: move every file to a temporary name, then to its final name. Or rename into a new, empty folder. A related trap: on Windows and macOS Photo.JPG and photo.jpg are the same file, so collision checks must ignore case. TidyBatch https://tidybatch.github.io/?utm source=devto&utm campaign=tidybatch is a free, open-source command-line tool we made it built around these rules. It previews by default, renames in two phases, checks collisions without case, and keeps a journal so you can undo with one command, even after an interrupted run. Install it with pipx install tidybatch , or try it without installing with uvx tidybatch . On a folder with three files: php $ tidybatch rename Downloads --slug --lower Café Menu.txt - cafe menu.txt Holiday Photo 1.JPG - holiday photo 1.jpg Report Final v2 .PDF - report final v2.pdf 3 file s would change. Dry run: nothing was changed. Add --apply to do it. $ tidybatch rename Downloads --slug --lower --apply Café Menu.txt - cafe menu.txt Holiday Photo 1.JPG - holiday photo 1.jpg Report Final v2 .PDF - report final v2.pdf 3 file s will change. Done. To revert: tidybatch undo "Downloads" journal: journal-20261103-010602-321629.json $ tidybatch undo Downloads Restored 3 file s , skipped 0. Journal: journal-20261103-010602-321629.json It runs locally and needs no account. rename and undo are free; the paid Pro 9 € adds organize and dedupe . More guides: tidybatch.github.io/guides https://tidybatch.github.io/guides/?utm source=devto&utm campaign=tidybatch . Code: github.com/tidybatch/tidybatch https://github.com/tidybatch/tidybatch . If you only use Windows and like clicking, PowerRename is excellent and free. TidyBatch is for when you want the same command on every OS, in scripts, with an undo that survives closing the window.