I have a large amount of files in a large amount of folders that I want to set to all have the same file extension. Using this works for single file ext
Get-ChildItem -File -Recurse | ForEach-Object { Rename-Item -Path $_.PSPath -NewName $_.Name.replace(".webp",".jpg")}
But using this for multiple files ext does nothing
Get-ChildItem -File -Recurse | ForEach-Object { Rename-Item -Path $_.PSPath -NewName $_.Name.replace(".jpeg.png.webp",".jpg")}
I have tried .* for the file ext to cover all of them and adding spaces between the exts but this does nothing either.
Can someone point out where I am being an idiot?
CodePudding user response:
To avoid renaming parts of the file name that are not the extension, I would advise against using -replace
, unless you treat it as it should by escaping the characters that have special meaning for regex (the dot) and by anchoring the string to replace.
Better use a dedicated .Net function:
(Get-ChildItem -Filter '*.jpeg','*.png','*.webp' -File -Recurse) | Rename-Item -NewName {[System.IO.Path]::ChangeExtension($_.Name, ".jpg")}
or if you do want to use -replace
:
(Get-ChildItem -Filter '*.jpeg','*.png','*.webp' -File -Recurse) | Rename-Item -NewName { $_.Name -replace '\.(jpeg|png|webp)$', '.jpg' }
Also, by specifying the extensions in the -Filter
parameter of Get-ChildItem, you do not iterate all files, eventhough they can have extensions you do not want to rename, plus Get-ChidItem will do its job faster.
CodePudding user response:
You can use |
for OR operations.
Get-ChildItem -File -Recurse | Rename-Item -NewName { $_.Name -replace "\.jpeg$|\.png$|\.webp$",".jpg" }
the \.
is needed to match a literal .
, and the $
is needed to tell the command to only match those three strings when they occur at the end of the filename.