Bulk & Automation

Batch Rename Every File in a Folder, Subfolders Included

Renaming the files in a single folder is easy. The moment your files are spread across nested subfolders, most tools quietly rename only the top level and miss everything deeper. This guide is about the harder version: batch renaming a whole folder tree, recursively, so files two and three levels down get the same treatment. It covers the recursive options on each platform, and the point where a folder full of meaningless names needs a tool that reads the files, not just a pattern.

Recursive Rename: Method by Platform

The key requirement here is reaching files in subfolders, not just the top level. Each platform has a way.

PlatformRecursive methodReaches subfolders?
Windows (script)Get-ChildItem -Recurse | Rename-ItemYes, with -Recurse
Windows (GUI)PowerToys PowerRenameYes, includes subfolder items
Mac / Linuxfind . -exec ... or rename with recursionYes, via find
Content-awarePoint the tool at the folder rootYes, reads the whole tree

Why 'a Folder' Usually Means 'a Folder Tree'

When people say they want to batch rename a folder, they often have subfolders too: a project folder with per-client subfolders, a photo library organized by year, a document archive by department. The trap is that the simplest tools, File Explorer's F2, a plain shell glob, only act on the current directory. Run them at the top and the files nested inside are untouched, so you think the batch worked when half of it didn't.

So the real question for a folder rename is whether the method is recursive. Everything below is chosen for that: reaching every file in the tree, not just the ones sitting at the top.

It helps to decide the scope before you run anything. Sometimes you want only the files sitting directly in one folder, sometimes you want every descendant no matter how deep the tree goes, and sometimes you want the whole tree except for a couple of subfolders you deliberately leave alone. Naming that intent up front, one folder versus all descendants, tells you which switch to reach for and stops you from either under-renaming the top level or accidentally rewriting a nested archive you meant to preserve.

Method 1: Recursive Rename on Windows

PowerShell handles a folder tree cleanly with the -Recurse switch on Get-ChildItem, which walks every subfolder:

  1. Preview first: Get-ChildItem -Path 'C:\Docs' -Recurse -Filter *.txt | Rename-Item -NewName { $_.Name -replace ' ','_' } -WhatIf
  2. Read the -WhatIf output to confirm files deep in the tree are included.
  3. Remove -WhatIf to apply the rename across the whole folder and its subfolders.
  4. For a no-script option, PowerToys PowerRename also includes items from selected subfolders and shows a live preview before applying.

Method 2: Recursive Rename on Mac and Linux

On macOS and Linux, find is the recursive workhorse. It walks the tree and runs a rename on each match: find . -type f -name '*.txt' -exec sh -c 'mv "$1" "${1%.txt}.md"' _ {} \; changes every .txt to .md throughout the folder and its subfolders. Where a plain for f in *.txt loop would only see the top directory, find reaches everything. On Linux specifically, the Perl rename utility combined with find covers recursive regex renames as well.

Watch for Name Collisions Across Subfolders

Recursion introduces a risk single-folder renames don't: two files in different subfolders can resolve to the same new name, and if you flatten or move them, one overwrites the other. Always preview (with -WhatIf on Windows, a dry run on the terminal) before applying a recursive rename, and keep files in their subfolders unless you specifically intend to merge them. That single habit prevents the most common way a folder-tree rename goes wrong.

Excluding Subfolders and Keeping the Structure Intact

Recursive does not have to mean everything. Often a folder tree has one or two subfolders you want left untouched, an originals folder, a done archive, a node_modules or export directory that has no business being renamed. On Windows you can filter those out by piping through Where-Object and testing the FullName, for example Get-ChildItem -Recurse | Where-Object { $_.FullName -notmatch '\\originals\\' }. On Mac and Linux, find takes a -prune expression that skips whole branches of the tree before it ever runs the rename. Building the exclusion into the command is safer than deleting files from a preview list by hand, because it applies the same rule every time you run it.

It is also worth being clear that renaming files inside a tree does not move them. Each file stays in the subfolder it lived in, so the folder structure, your per-client, per-year, or per-department layout, survives the operation. That matters when the folders themselves carry meaning: a file named 2024-invoice.pdf inside a Client-A folder is already half-labelled by its location, and a good recursive rename can fold that per-folder context into the filename so each file reads correctly even after it is copied out of the tree.

Once the Folder Is Renamed, Make the Names Mean Something

Recursive renaming solves reach, every file in the tree gets touched, but it doesn't solve meaning. If the folder is full of Scan0043.pdf and IMG_2938.jpg, a recursive pattern rename just gives you consistently prefixed or numbered versions of the same mystery. The names still don't tell you what any file is.

That's the point where naming by content matters. A content-aware tool reads each file across the whole folder and names it from what's inside, the vendor on an invoice, the parties on a contract, the subject of a scan, so the tree becomes searchable, not just tidy. You point it at the folder root and it processes the whole structure, the same recursive reach as the methods above, but producing meaningful names rather than patterned ones. For that approach, see the bulk rename software overview.

The two are complementary: use a recursive pattern rename when the change is structural (extensions, prefixes, cleanup across a tree), and reach for content-aware renaming when the folder's files need names that describe them and only the documents themselves hold that information.

Frequently Asked Questions

How do I batch rename all files in a folder including subfolders?

Use a recursive method. On Windows, Get-ChildItem -Recurse piped to Rename-Item walks every subfolder; on Mac and Linux, find does the same. Preview with -WhatIf or a dry run first to confirm nested files are included.

Why does my rename only affect the top folder?

Because the tool isn't recursive. File Explorer's F2 and a plain shell glob only see the current directory. Add -Recurse in PowerShell, use find on Mac/Linux, or use a tool that processes the whole folder tree.

What's the risk when renaming across subfolders?

Name collisions: two files in different subfolders can resolve to the same new name. If you move or flatten them, one overwrites the other. Preview before applying and keep files in their subfolders unless you mean to merge them.

How do I make the renamed files' names actually descriptive?

A pattern rename only reshapes existing names. To name files by what they contain, an invoice's vendor, a contract's parties, use content-aware renaming, which reads each file across the folder and builds a descriptive name from its contents.

Can I rename a whole folder of scanned documents by content?

Yes. Point a content-aware tool at the folder root and it reads each scan with OCR, extracts the identifying details, and names the files across the tree, turning an unsearchable folder into a searchable one.

How do I recurse into subfolders but skip a few I want left alone?

Filter the recursive listing before you rename. In PowerShell, pipe Get-ChildItem -Recurse through Where-Object and exclude paths that match the folders you want to protect. On Mac and Linux, use find with a -prune expression to skip those branches entirely. Building the exclusion into the command means the same subfolders are spared every time you run it.

Can the rename keep the subfolder each file lives in?

Yes. A recursive rename changes names in place, so every file stays in its original subfolder and the folder structure is preserved. If the folders carry meaning, such as a client or year, a content-aware rename can also pull that per-folder context into the filename so each file still reads correctly once it leaves the tree.