How-to & Workflow

Batch Script to Rename Files on Windows (the .bat Way)

There's a particular kind of satisfaction in a batch script you can double-click. You point it at a folder, it renames everything in one pass, and the next time the same job comes around you just run it again. No install, no license, no cloud. This guide is the classic Windows .bat approach: renaming files from cmd.exe using the ren command, FOR loops, and wildcards, then saving those commands as a reusable script. It's genuinely great for pattern jobs. It is also honestly blind to the one thing people most often want, the actual content inside each file, and we'll be straight about exactly where that wall is.

What a Batch Script Is Good At (and What It Can't See)

A batch script, a plain text file saved with a .bat extension, is just a list of cmd.exe commands that run top to bottom when you double-click it. For renaming files, that's a surprisingly capable little tool. If your job is uniform, add a prefix, change an extension, number a sequence, strip a common chunk of text, a handful of lines gets it done, and you keep the file forever to run again next month.

The honest boundary is this: a batch script works on filenames, not on file contents. It matches names by pattern and rewrites them by pattern. It never opens the file, never reads the text on the page, never knows that scan_0007.pdf is an Acme invoice dated the 14th. If the new name you want is already sitting in the old name, cmd can rearrange it. If the new name lives inside the document, cmd cannot reach it. Keep that line in mind and everything below fits into place.

The rest of this guide builds up in order: the ren command for simple renames, FOR loops for doing it across many files with a counter, saving and scheduling the result, and finally a clear map of where cmd stops and you need PowerShell or a content-aware tool instead.

Rename Files With the ren Command

The foundation of any rename batch script is the ren command (rename works identically, it's the same command). At its simplest, ren oldname.txt newname.txt renames one file. The syntax is always ren <what to match> <what to make it>.

Where ren earns its keep is wildcards. The asterisk stands in for any run of characters, and the question mark for a single character. So ren *.txt *.bak renames every .txt file in the folder to the same base name with a .bak extension in one line. ren report_*.pdf 2025_*.pdf swaps a leading report_ for 2025_ across a whole batch. The wildcard positions in the second argument map to the matched positions in the first, which is what makes bulk extension and prefix changes a one-liner.

Two limits are worth knowing up front, because they shape everything after. First, ren cannot move a file. The target is always a name in the same folder, so you cannot use ren to rename and relocate in one step. Second, ren has no counter of its own. It can copy characters from the old name into the new name, but it cannot generate fresh incrementing text like 001, 002, 003 by itself. The moment you want sequential numbering, you have to step up to a FOR loop and supply the counter yourself.

Looping With FOR in a Batch File

To rename many files with logic, ren goes inside a FOR loop. FOR walks a set of files and runs a command for each one. A basic pass over every PDF in the current folder looks like for %%f in (*.pdf) do ren "%%f" "renamed_%%f", where %%f holds each filename in turn. Use FOR /R instead of plain FOR when you want to recurse into subfolders and rename files in a whole tree, not just one directory.

One syntax trap catches everyone once: inside a saved .bat file the loop variable takes two percent signs (%%f), but if you type the same command directly at the cmd prompt it takes one (%f). Same command, different percent count, purely because a .bat file needs the doubled form to survive parsing. If a loop that worked at the prompt fails in your script, this is usually why.

Sequential numbering is the classic reason to loop, and it needs one more piece. Because cmd expands variables when it reads a line, a counter you increment inside the loop won't update the way you expect unless you turn on delayed expansion. Put SETLOCAL ENABLEDELAYEDEXPANSION at the top of the script, keep a counter like set /a n+=1 inside the loop, and reference it with exclamation marks, !n!, rather than percent signs. A working shape is: SETLOCAL ENABLEDELAYEDEXPANSION, set n=0, then for %%f in (*.pdf) do set /a n+=1 followed by ren "%%f" "invoice_!n!.pdf". That renames the folder to invoice_1.pdf, invoice_2.pdf, and so on. If you want zero-padded numbers like 001, you build the padding by hand with a bit of string slicing, since cmd has no format specifier for it, which is exactly the kind of fiddliness that eventually pushes people toward PowerShell.

Saving and Reusing the Script

The payoff of the whole exercise is reuse. Open Notepad, paste your ren and FOR commands, and save the file with a .bat extension (in the save dialog, set the file type to All Files so it doesn't become rename.bat.txt). From then on, double-clicking that file runs every command in order against whatever folder it points at.

Make the script readable while you're at it. Any line beginning with REM is a comment that cmd ignores, so REM Rename all scans to invoice_N.pdf above your loop tells future-you what the script does. A line reading @echo off at the very top hides the commands themselves and just shows results, which makes the window far less noisy.

For recurring jobs you can hand the script to Windows Task Scheduler and have it run on a schedule or at logon, so a nightly folder tidy happens without you touching it. One rule matters more than any of this: test on a copy first. A batch rename has no undo. If a wildcard is slightly off, cmd will happily rename a hundred files the wrong way in a fraction of a second and there is no Ctrl+Z to bring the old names back. Duplicate the folder, run the .bat against the copy, confirm the names came out right, and only then point it at the real files.

Where cmd Batch Scripts Stop

Two walls end the batch-script road, and it's better to meet them here than mid-project.

The first is regex. cmd.exe has no real regular-expression engine. FOR can do limited substring substitution (a FOR variable supports replacing one fixed piece of text with another, like %%~nf with a chunk swapped out), but anything that needs true pattern matching, capture groups, reformatting a date buried in the middle of a name, conditionally reordering parts, matching variable structures, is either painful or flatly impossible in a .bat. This is the natural moment to move to PowerShell, whose Rename-Item paired with the -replace operator and .NET regex handles those transformations cleanly. If your job is really a regex job, don't fight cmd for it.

The second wall is the one this whole guide has been pointing at: content. A batch script renames by name, and only by name. It cannot open a PDF and read the vendor, the invoice number, or the date off the page, because it never looks inside the file at all. For a scanned document this is absolute. A scan is an image with no text layer, so even a tool that could read text would find nothing without OCR, and cmd reads no text either way. True content-based renaming needs text extraction for born-digital PDFs or OCR for scans, and cmd.exe does neither. That capability lives in a different category of tool entirely, and it's the right place to hand the job off when the name you want is printed on the page rather than sitting in the old filename.

What a Batch Script Can and Can't Do

TaskBatch (.bat / cmd) approachPossible?
Simple pattern / extension renameren with wildcards, e.g. ren *.txt *.bakYes
Sequential numberingFOR loop with a counter variableYes, with delayed expansion
Find-and-replace across namesLimited string substitution inside a FOR variablePartly
Regex reformat of namesNo regex engine in cmdNot in cmd, use PowerShell
Content-based name from a scancmd never reads file contentsNot possible, needs OCR

When to Reach Past a Batch Script

It's worth being fair to the .bat approach, because it deserves it. A batch script is free, it's already on every Windows machine, it takes no install and no account, and once written it's reusable forever. For a uniform pattern job on a consistent folder, add a prefix, fix a batch of extensions, number a set of files, it is genuinely the right tool, and reaching for anything heavier would be over-engineering a solved problem.

The line to watch is where the new name has to come from inside the files. A batch script can rearrange what's already in a filename, but it cannot read a vendor name, a date, or an invoice number off the page, and with scanned documents there's no text in the file at all until something runs OCR on it. That's the point where a .bat simply can't get there, no matter how clever the loop. What you need instead is a content-aware tool that bundles OCR and naming together: it reads each document, whether it's born-digital or a scan, suggests a descriptive filename from what it actually found, and shows you a preview so you confirm before anything is renamed. That preview step is the safety net a raw batch script never has. It's the gap renamer.ai was built to fill, and it's the honest answer when your folder is full of scans rather than tidy patterns. For the wider workflow around that, the scanned-PDF workflow hub covers the content-aware side in depth.

The Short Version

A batch script to rename files is one of the most useful hundred bytes of text you'll ever save. Use ren with wildcards for simple pattern and extension changes, wrap it in a FOR loop with delayed expansion when you need sequential numbering, save it as a .bat, test it on a copy because there's no undo, and schedule it if the job repeats. Reach for PowerShell the moment you need real regex, and reach for a content-aware tool the moment the name has to come from inside the file, especially with scans, since cmd can never read a page. If your job is patterns, a .bat wins on simplicity and cost; if it's content, the scanned-PDF workflow hub is the better next step.

Frequently Asked Questions

How do I write a batch file to rename multiple files?

Open Notepad, write a FOR loop that runs ren on each file, and save it with a .bat extension. A minimal example that adds a prefix to every PDF in the folder is: for %%f in (*.pdf) do ren "%%f" "renamed_%%f". Remember the loop variable takes two percent signs (%%f) inside a saved .bat but only one (%f) if you type it at the prompt. Test the script on a copy of the folder first, since a batch rename has no undo.

Can a batch script rename files with sequential numbers?

Yes, but you have to supply the counter yourself, because ren has no numbering of its own. Put SETLOCAL ENABLEDELAYEDEXPANSION at the top of the script, initialize a counter with set n=0, then inside the loop do set /a n+=1 and reference it with exclamation marks: ren "%%f" "invoice_!n!.pdf". Delayed expansion is what makes the counter update on each pass. Zero-padded numbers like 001 need extra string handling by hand, which is where many people switch to PowerShell.

Can a batch script rename files based on their content?

No. A batch script works on filenames only. It never opens a file or reads the text inside it, so it cannot pull a vendor, a date, or an invoice number off the page and put it in the name. This is absolute for scanned documents, which are images with no text layer at all. Content-based renaming needs text extraction for born-digital PDFs or OCR for scans, and cmd.exe does neither. For that you need a content-aware tool that reads the document and suggests a name from what it finds.

Should I use a batch file or PowerShell to rename files?

Use a batch file for simple, uniform jobs: extension changes, prefixes, and basic sequential numbering are quick and require nothing to install. Use PowerShell when you need real pattern power, because its Rename-Item command with the -replace operator supports genuine regular expressions, which cmd does not. In short, reach for a .bat for straightforward pattern renames and PowerShell for anything that needs regex or more complex logic. If the new name must come from inside the file, neither one can do it and you need a content-aware tool with OCR.