Home > Net >  Bulk renaming files with different extensions in order using powershell
Bulk renaming files with different extensions in order using powershell

Time:03-09

is there a way to bulk rename items such that a folder with the items arranged in order would have their name changed into numbers with zero padding regardless of extension?

for example, a folder with files named:

file1.jpg
file2.jpg
file3.jpg
file4.png
file5.png
file6.png
file7.png
file8.jpg
file9.jpg
file10.mp4

would end up like this:

01.jpg
02.jpg
03.jpg
04.png
05.png
06.png
07.png
08.jpg
09.jpg
10.mp4

i had a script i found somewhere that can rename files in alphabetical order. however, it seems to only accepts conventionally bulk renamed files (done by selecting all the files, and renaming them such that they read "file (1).jpg" etc), which messes up the ordering when dealing with differing file extensions. it also doesn't seem to rename files with variations in their file names. here is what the code looked like:

Get-ChildItem -Path C:\Directory -Filter file* | % { 
    $matched = $_.BaseName -match "\((?<number>\d )\)"
    if (-not $matched) {break;}
    [int]$number = $Matches["number"]
    Rename-Item -Path $_.FullName -NewName "$($number.ToString("000"))$($_.Extension)"
}

CodePudding user response:

If your intent is to rename the files based on the ending digits of their BaseName you can use Get-ChildItem in combination with Where-Object for filtering them and then pipe this result to Rename-Item using a delay-bind script block.

Needles to say, this code does not handle file collision. If there is more than one file with the same ending digits and the same extension this will error out.

Get-ChildItem -Filter file* | Where-Object { $_.BaseName -match '\d $' } |
Rename-Item -NewName {
    $basename = '{0:00}' -f [int][regex]::Match($_.BaseName, '\d $').Value
    $basename   $_.Extension
}

To test the code you can use the following:

@'
file1.jpg
file2.jpg
file3.jpg
file4.png
file5.png
file6.png
file7.png
file8.jpg
file9.jpg
file10.mp4
'@ -split '\r?\n' -as [System.IO.FileInfo[]] | ForEach-Object {
    $basename = '{0:00}' -f [int][regex]::Match($_.BaseName, '\d $').Value
    $basename   $_.Extension
}

CodePudding user response:

You could just use the number of files found in the folder to create the appropriate 'numbering' format for renaming them.

$files = (Get-ChildItem -Path 'D:\Test' -File) | Sort-Object Name
# depending on the number of files, create a formating template 
# to get the number of leading zeros correct. 
# example: 645 files would create this format: '{0:000}{1}'
$format = '{0:'   '0' * ($files.Count).ToString().Length   '}{1}' 

# a counter for the index number
$index  = 1 
# now loop over the files and rename them
foreach ($file in $files) {
    $file | Rename-Item -NewName ($format -f $index  , $file.Extension) -WhatIf
}

The -WhatIf switch is a safety measure. With this, no file gets actually renamed, you will only see in the console what WOULD happen. Once you are content with that, remove the -WhatIf switch from the code and run again to rename all your files in the folder

  • Related