Replace Part of Filename if Filename Already Exists - powershell

In this question, How do I rename part of a filename, if the newly renamed filename already exists? Want the newly attempted filename to overwrite the existing file. Also want to rename folders within folders within folders.
Replace "Default" with "VOD" in filename,
Replace Part of File Name Powershell
Get-ChildItem Default_*.csv |
Rename-Item -NewName {$_.Name -replace '^Default','VOD'}
ls *.csv | Rename-Item -NewName {$_.Name -replace "Default","VOD"}
Solution here was not working with -Force:
Get-ChildItem *.* -File -Recurse |
Rename-Item -NewName {$_.Name -replace 'Default','VOD'} -Force

As per this question and answer: rename-item and override if filename exists
Use Move-Item and -Destination, and also swap $_.Name for $_.FullName (if you don't do that it will throw everything into your current directory, because Name is just the name of the file, not the full path). Check using -WhatIf to see what operations will be carried out, just in case:
With -WhatIf:
Get-ChildItem *.* -File -Recurse |
Move-Item -Destination {$_.FullName -replace 'Default','VOD'} -WhatIf
Output:
What if: Performing the operation "Move File" on target "Item: C:\temp\pstest\Default_77.txt Destination: C:\temp\pstest\VOD_77.txt".
Now with -Force:
When you're comfortable with the output from using the -WhatIf parameter, change it to -Force to complete the file move.
Get-ChildItem *.* -File -Recurse |
Move-Item -Destination {$_.FullName -replace 'Default','VOD'} -Force

Related

Powershell: Rename all files in folders and subfolders that are named "cover.jpg" to "folder.jpg"

I have a folder called Music. This folder contains subfolders for albums. In each folder is .jpg file named cover.jpg which represents the cover of the album. I want to recursively rename all files named "cover*.jpg to folder.jpg.
I've tried this:
Get-ChildItem -Path O:\FILES_IN_PROCESS\!!FINISHED!!\_MUSIC "*cover*.jpg" -Recurse | ForEach-Object {Rename-Item $_ -NewName ('folder.jpg')
And this:
Get-ChildItem -Recurse O:\FILES_IN_PROCESS\!!FINISHED!!\_MUSIC | where {$_.Name -ilike "Cover.jpg"} {Rename-Item $_ -NewName ('folder.jpg')}
but I get errors each time
Let Rename-Item receive the object's from pipeline, this way the objects are always bound by Property Name using their .PSPath property (PowerShell Provider Path) to the cmdlet's -LiteralPath parameter.
Get-ChildItem -LiteralPath 'O:\FILES_IN_PROCESS\!!FINISHED!!\_MUSIC' -Filter '*cover*.jpg' -Recurse |
Rename-Item -NewName 'folder.jpg'

Powershell - Multiple file ext on rename doesnt work

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?
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.
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.

Replace exact part of file name with Powershell

I tried the code found here without success.
What I need is to replace an exact text with another, but this code doesn't seem to deal with exact text.
This is the code I used, and what I need is, for example, for a file name that ends with ".L.wav" to be replaced with "_L.wav", but what happens is that powershell tries to rename even the file that ends with ".BL.wav" into "_L.wav".
Thank you.
ls *.* | Rename-Item -NewName {$_.name -replace ".L.wav","_L.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".LFE.wav","_LFE.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".R.wav","_R.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".BL.wav","_LSR.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".BR.wav","_RSR.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".SL.wav","_LSS.wav"}
ls *.* | Rename-Item -NewName {$_.name -replace ".SR.wav","_RSS.wav"}
Read-Host -Prompt "Press Enter to exit" ```
The dot in regex means Any Character. Without escaping that, things go wrong.
Try
Rename-Item -NewName {$_.Name -replace ('{0}$' -f [regex]::Escape('.L.wav')),'_L.wav'}
or manually escape the regex metacharacters:
Rename-Item -NewName {$_.Name -replace '\.L\.wav$','_L.wav'}
The $ at the end anchors the text to match at the end on the string
Also, instead of doing ls *.* | Rename-Item {...}, better use
(Get-ChildItem -Filter '*.L.wav' -File) | Rename-Item {...}
(ls is alias to Get-ChildItem )
Using the -Filter you can specify what files you're looking for.
Using the -File switch, you make sure you do not also try to rename folder objects.
By surrounding the Get-ChildItem part of the code in brackets, you make sure the gathering of the files is complete before you start renaming them. Otherwise, chances are the code will try and keep renaming files that are already processed.

I get errors when trying to rename files

I have files in a folder C:\Users\xxx\Documents\Projects\files\old\. I have built a loop to rename them but it doesn't work out:
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
Rename-Item -Path $file.FullName -NewName $newfiles+"$($entry.Custom_ID).$($file.BaseName).PDF"
How do I concatenate properly $newfiles to the rename path? I tried everything but keep getting errors:
Rename-Item : A positional parameter cannot be found that accepts argument '-'
you need to either copy and rename or move and rename files.using -whatif is a good practise because it shows you what is going to happen if you execute a particular command.
Notice also i am using a filter to get-childitem to only get the pdf files so that i know that the files i am going to rename will only be pdf files. of course if the oldfiles folder only contains pdf files then you dont need to use the filter.
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
$oldfiles = "C:\Users\xxx\Documents\Projects\files\old\"
Get-ChildItem -Path $oldfiles -Filter *.pdf |
Move-Item -Destination {Join-Path -Path $newfiles -ChildPath "$($entry.Custom_ID).$($_.BaseName).pdf"} -WhatIf
or
Get-ChildItem -Path $oldfiles -Filter *.pdf |
copy-Item -Destination {Join-Path -Path $newfiles -ChildPath "$($entry.Custom_ID).$($_.BaseName).pdf"} -WhatIf
This is how I always concatenate things in Powershell:
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
Rename-Item -Path $file.FullName -NewName ("{0}{1}.PDF" -f $newfiles,$($entry.Custom_ID).$($file.BaseName))
From experience, this always works.

cannot rename because the target specified represents a path or device name

Get-ChildItem "C:\temp\test\testsub" -Recurse -Include *.wav | %{Rename-Item $_ -NewName ("$.Directory.Name.Substring(4)"+"($.Name).wav")}
produces error I do not understand
[ERROR] Cannot rename because the target specified represents a path or device name.
as others mentioned, one can only guess at what you are trying to accomplish, so here is my guess.
remove -whatif to make the changes happen
Get-ChildItem 'C:\temp\test\testsub' -Recurse -Include *.wav | % {rename-item $_.fullname $($_.directory.name.substring(0, 4) + '-' + $_.name) -whatif}