Rename files, keep old incremented file order - powershell

I have used this to rename and increment file names with PowerShell:
$nr = 1
DIR | % { Rename-Item $_ -NewName ('File{0}.jpg' -f $nr++) }
It works but it seem it is renaming the files in the order of creation date.
I have 500 files each bulked in folders of 100 pics each, all with the order 1-100. The results would be 'picturename'1-500.jpg.
So I need to be able to tell what the first number will be:
'screenshot (9).jpg'
'screenshot (10).jpg'
'screenshot (11).jpg'
etc
I need to rename them to:
'picture109.jpg'
'picture110.jpg'
'picture111.jpg'
etc
Any suggestions how to do this?

Why not sort the results of dir before renaming the files to ensure you have the appropriate order ?
$nr = 1
dir | sort Name | % { Rename-Item $_ -NewName ('File{0}.jpg' -f $nr++) }
With PS complete syntax :
$nr = 1
Get-ChildItem | Sort-Object Name | % { Rename-Item $_ -NewName ('File{0}.jpg' -f $nr++) }

Related

Batch renaming files by PowerShell?

How can I rename files in a folder that have random names and random extensions to a sequence like the example below: 0001.pdf 0002.pdf ..... 0100.png and continue.
And if possible then generate a .txt file with the names and extensions generated.
For the .txt file if not possible Powershel could be another application.
Searching I got the code below, but I can't fix it for the task I need.
Dir | Rename-Item –NewName { $_.name –replace " - ","0" }
Wrap the call to Rename-Item in ForEach-Object then maintain a counter in a variable:
$fileNumber = 1
Get-ChildItem path\to\folder\containing\random\files -File |ForEach-Object {
# Construct new file name
$newName = '{0:0000}{1}' -f $fileNumber,$_.Extension
# Perform rename
$_ |Rename-Item -NewName $newName
# Increment number
$fileNumber++
}

Bulk renaming files with different extensions in order using powershell

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)"
}
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
}
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

Powershell rename filename by replacing n characters in ascending order

I've got a number of files in the following format
I'd like to replace the 3 characters after 60- in ascending order.
I have used the following code to remove the first 28 characters
get-childitem * | rename-item -newname{string.substring(28)}
Then rename using the following
$i = 1
dir | ForEach-Object {$_ | Rename-Item -NewName ('00092-100221-XX-A-233-60-{0:D3} {1}{2}' -f $i++, $.BaseName, $.Extension)}
However I end up losing the original file order. Is there a way I can rename these files by keeping the original file order and also maybe less time consuming?
You can do all in one step, thus preserving the original file order:
$script:i = 1
Get-ChildItem | Rename-Item -NewName {
'00092-100221-XX-A-233-60-{0:D3}{1}' -f $script:i++, $_.Name.SubString(28)
}
(Note that I excplicitly specified the scope for $i, otherwise the value wouldn't be increased.)

Search and replace files and folders names with txt file support

I have many folders and inside these different files. Each folder and their children files have the same name and different extension, so in the ABC folder there are the ABC.png, ABC.prj, ABC.pgw files, in the DEF folder there are the DEF.png, DEF.prj, DEF.pgw files and so on.
With a script I have created a txt file with the list of png file names. Then I put in row 2 a new name for the name in row1, in row 4 a new name for the name in row 3, and so on.
Now I'm searching a powershell script that:
- scan all folder for the name in row 1 and replace it with name in row2
- scan all folder for the name in row 3 and replace it with name in row4 and so on
I have try with this below, but it doesn't work.
Have you some suggestions? Thank you
$0=0
$1=1
do {
$find=Get-Content C:\1\Srv\MapsName.txt | Select -Index $0
$repl=Get-Content C:\1\Srv\MapsName.txt | Select -Index $1
Get-ChildItem C:\1\newmaps -Recurse | Rename-Item -NewName { $_.name -replace $find, $repl} -verbose
$0=$0+2
$1=$1+2
}
until ($0 -eq "")
I believe there are several things wrong with your code and also the code Manuel gave you.
Although you have a list of old filenames and new filenames, you are not using that in the Get-ChildItem cmdlet, but instead try and replace all files it finds.
Using -replace uses a Regular Expression replace, that means the special character . inside the filename is regarded as Any Character, not simply a dot.
You are trying to find *.png files, but you do not add a -Filter with the Get-ChildItem cmdlet, so now it will return all filetypes.
Anyway, I have a different approach for you:
If your input file C:\1\Srv\MapsName.txt looks anything like this:
picture1.png
ABC_1.png
picture2.png
DEF_1.png
picture3.png
DEF_2.png
The following code will use that to build a lookup Hashtable so it can act on the files mentioned in the input file and leave all others unchanged.
$mapsFile = 'C:\1\Srv\2_MapsName.txt'
$searchPath = 'C:\1\NewMaps'
# Read the input file as an array of strings.
# Every even index contains the file name to search for.
# Every odd index number has the new name for that file.
$lines = Get-Content $mapsFile
# Create a hashtable to store the filename to find
# as Key, and the replacement name as Value
$lookup = #{}
for ($index = 0; $index -lt $lines.Count -1; $index += 2) {
$lookup[$lines[$index]] = $lines[$index + 1]
}
# Next, get a collection of FileInfo objects of *.png files
# If you need to get multiple extensions, remove the -Filter and add -Include '*.png','*.jpg' etc.
$files = Get-ChildItem -Path $searchPath -Filter '*.png' -File -Recurse
foreach ($file in $files) {
# If the file name can be found as Key in the $lookup Hashtable
$find = $file.Name
if ($lookup.ContainsKey($find)) {
# Rename the file with the replacement name in the Value of the lookup table
Write-Host "Renaming '$($file.FullName)' --> $($lookup[$find])"
$file | Rename-Item -NewName $lookup[$find]
}
}
Edit
If the input text file 'C:\1\Srv\MapsName.txt' does NOT contain filenames including their extension, change the final foreach loop into this:
foreach ($file in $files) {
# If the file name can be found as Key in the $lookup Hashtable
# Look for the file name without extension as it is not given in the 'MapsName.txt' file.
$find = [System.IO.Path]::GetFileNameWithoutExtension($file.Name)
if ($lookup.ContainsKey($find)) {
# Rename the file with the replacement name in the Value of the lookup table
# Make sure to add the file's extension if any.
$newName = $lookup[$find] + $file.Extension
Write-Host "Renaming '$($file.FullName)' --> '$newName'"
$file | Rename-Item -NewName $newName
}
}
Hope that helps
The problem in your snippet is that it never ends.
I tried it and it works but keeps looping forever.
I created a folder with the files a.txt, b.txt and c.txt.
And in the map.txt I have this content:
a.txt
a2.md
b.txt
b2.md
c.txt
c2.md
Running the following script I managed to rename every file to be as expected.
$0=0
$1=1
$find=Get-Content D:\map.txt | Select -Index $0
while($find) {
$find=Get-Content D:\map.txt | Select -Index $0
$repl=Get-Content D:\map.txt | Select -Index $1
if(!$find -Or !$repl) {
break;
}
Get-ChildItem D:\Files -Recurse | Rename-Item -NewName { $_.name -replace $find, $repl} -verbose
$0=$0+2
$1=$1+2
}

How to rename files with sequential even and odd numbers in PowerShell?

I would like to know how I can rename the files from a specific folder with a sequence of only even and odds numbers in PowerShell. E.g. Folder1: pag_001.jpg, pag_003.jpg, pag_005.jpg.... pag_201.jpg , Folder2: pag_002.jpg, pag_004.jpg, pag_006.jpg.... pag_200.jpg. It is because I have a document that was scanned first the odds pages and secondly the even pages, therefore their file names are in a consecutive sequence from 1 to 201. Then I separated one half of the files which are the odds pages in a new place: Folder1, and the second half,the even pages in the Folder2. That is why I would like change the names first and the join again together with their new names.
I have tried this based in a similar post:
At the moment I could generate even number sequences like that:
ForEach ($number in 1..100 ) { $number * 2}
and odd numbers like that:
ForEach ($number in 0..100 ) { $number *2+1}
and wanted apply the sequences generated before to rename my files like that:
cd C:\test\Folder1
$i = $number * 2
Get-ChildItem *.jpg | %{Rename-Item $_ -NewName ('pag_{0:D3}.jpg' -f $i++)}
but it doesn't works! Any suggestions are welcome
Regards,
Your $i++ adds 1 each time, this is why it also add even numbers,
You can create array of Odd Numbers then use the $i++ to step one item in the array, like this:
$path = "C:\test\Folder1"
$oddNumbersArray = 0..100 | % {$_ *2 +1}
$i = 0
Get-ChildItem $path -Filter *.jpg | % {Rename-Item $_ -NewName ("pag_$($oddNumbersArray[$i]).jpg") ;$i++}
For Even Numbers change the $oddNumbersArray line to {$_ *2}
Bunch of ways to do this. For mine we add each index as a member so that it is more easily accessible in the rename item script block.
$index = 0
Get-ChildItem $path -Filter "*.jpg" | ForEach-Object{
$index = $index +2
$_ | Add-Member -Name "Index" -MemberType NoteProperty -Value $index -PassThru
} | Rename-Item -NewName {'pag_{0:D3}.jpg' -f $_.Index} -WhatIf
Using Add-Member in a ForEach-Object we update the value of index and then add it as a property of the same name. Then in your rename-item scriptblock we can call that property. Remove the -WhatIf after you verified the new names are what you wanted. Switch $index between 0 and -1 for even and odd respectively.
Another method using a global index variable and mitigating the pipeline by using calculated properties to create the pipeline variables that Rename-Item uses.
$path = "C:\Temp\csv"
$global:index = 0 # Use -1 for odd
Get-ChildItem $path -Filter "*.csv" |
Select-Object #{Name="Path";Expression={$_.FullName}},
#{Name="NewName";Expression={$global:index = $global:index + 2; 'pag_{0:D3}.jpg' -f $global:index}} |
Rename-Item -WhatIf