When dealing with hundreds of image files in a directory like family_pics
, manually renaming each file to follow a consistent pattern becomes tedious. The goal is to transform filenames like img123.jpg
into family_pics_1.jpg
while preserving file extensions.
Windows PowerShell provides powerful file manipulation features through the Get-ChildItem
cmdlet and pipeline operations. Here's a complete solution that handles:
- Directory name extraction
- Sequential numbering
- Extension preservation
- Recursive processing
$directory = "C:\\family_pics"
$files = Get-ChildItem -Path $directory -File -Recurse
$counter = 1
foreach ($file in $files) {
$newName = "{0}_{1}{2}" -f $file.Directory.Name, $counter++, $file.Extension
Rename-Item -Path $file.FullName -NewName $newName
}
For production use, we should add validation and duplicate handling:
param(
[string]$Path = (Get-Location).Path,
[switch]$Recursive = $false,
[string]$Prefix = ""
)
try {
$options = @{File = $true}
if ($Recursive) { $options.Recurse = $true }
$files = Get-ChildItem -Path $Path @options |
Where-Object { $_.Name -notlike "$($_.Directory.Name)_*" }
$counter = 1
foreach ($file in $files) {
$baseName = if ($Prefix) { $Prefix } else { $file.Directory.Name }
$newName = "{0}_{1}{2}" -f $baseName, $counter++, $file.Extension
$newPath = Join-Path $file.Directory.FullName $newName
if (Test-Path $newPath) {
Write-Warning "Skipping duplicate: $newName"
continue
}
Rename-Item -Path $file.FullName -NewName $newName -Force
}
}
catch {
Write-Error "Renaming failed: $_"
}
Run the script in different ways:
# Basic usage
.\RenameFiles.ps1 -Path "C:\\family_pics"
# With custom prefix
.\RenameFiles.ps1 -Path "C:\\vacation_photos" -Prefix "summer2023"
# Recursive processing
.\RenameFiles.ps1 -Path "C:\\projects" -Recursive
For simple cases, you can use Command Prompt:
@echo off
setlocal enabledelayedexpansion
set count=1
for %%f in (*.jpg) do (
ren "%%f" "family_pics_!count!.jpg"
set /a count+=1
)
Every developer encounters situations where they need to standardize file names across directories. The manual approach becomes tedious when dealing with:
- Hundreds of files in nested folders
- Different file extensions mixed in the same directory
- Need to maintain original file order during renaming
Windows PowerShell provides robust file system manipulation capabilities. Here's why it's perfect for this task:
# Basic rename operation demonstration
Get-ChildItem -Path "C:\family_pics\*.jpg" |
Rename-Item -NewName {"family_pics_$($_.BaseName.Split('img')[1]).jpg"}
This script handles all requirements:
function Rename-FilesRecursive {
param (
[string]$rootPath = (Get-Location).Path,
[switch]$preview
)
$files = Get-ChildItem -Path $rootPath -File -Recurse
foreach ($file in $files) {
$dirName = $file.Directory.Name
$counter = 1
$newName = "{0}_{1}{2}" -f $dirName, $counter, $file.Extension
while (Test-Path -Path (Join-Path -Path $file.Directory.FullName -ChildPath $newName)) {
$counter++
$newName = "{0}_{1}{2}" -f $dirName, $counter, $file.Extension
}
if ($preview) {
Write-Host "Would rename: $($file.Name) -> $newName"
} else {
Rename-Item -Path $file.FullName -NewName $newName
}
}
}
# Usage examples:
# Rename-FilesRecursive -rootPath "C:\family_pics"
# Rename-FilesRecursive -rootPath "C:\projects" -preview
For production-grade solutions, you might want to add:
# Parallel processing for large directories
$files | ForEach-Object -Parallel {
# Renaming logic here
} -ThrottleLimit 5
# Extension filtering
Get-ChildItem -Include *.jpg,*.png -Recurse
# Progress reporting
Write-Progress -Activity "Renaming Files" -Status "Processing..."
For those preferring other methods:
- CMD Batch:
for /r %i in (*) do @echo "%~nxi"
- Python Script: Using os.walk() and shutil.move()
- Third-party Tools: Bulk Rename Utility, Advanced Renamer
Always implement safeguards:
# Dry run first
Rename-FilesRecursive -preview
# Create backups
Copy-Item -Path $file.FullName -Destination "\\backup\$($file.Name)"