Powershell Changing Bulk File Extensions All At Once - powershell

Long story short: need to change multiple file extensions that are . (in Windows, the file extension is just a .) to .csv. I am able to do this in command prompt with this:
ren *. *.csv
But when I try to rename in Powershell, it only changes the first file (result: .csv.csv.csv.csv.csv.csv.csv) while the rest of the files remain untouched. I used this command:
Dir | Rename-Item -NewName { $_.name -replace ".",".csv" }
Can someone explain what I'm doing wrong and how come the first file is being renamed as such? Don't understand why Powershell makes it more complicated since it is based off CMD.

-replace is using regular expression matching where . will match any character so every character is replaced with .csv. Try this to replace *.txt and *.file with *.csv
gci -File | Rename-Item -NewName { $_.name -replace "\.(txt|file)$", ".csv" }
The question has changed. If your files really end in . which I can't actually reproduce then -replace "\.$", ".csv" where \. matches a literal dot and $ matches the end of the line.
If your files have no extension at all then you could do -replace "$", ".csv"
Or you could filter for files with no extension and just add one
gci -File |? Extension -eq '' |% { Rename-Item $_.FullName -NewName "$($_).csv" }

Get-ChildItem -Path C:\ -File | ForEach {Rename-Item $_.FullName -NewName ($_.name).Replace(".txt",".csv")}
Using dot notation, it reads characters as such; meaning no need in escaping any special chars.

Related

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.

How to use powershell to remove spaces from the beginning of a filename

I've been using the below to replace spaces in all the filenames and folders under the current directory location with underscores.
dir -Force -Recurse | Rename-Item -NewName {$_.name -replace " ","_"}
How do I specify to only replace spaces if they are at the the beginning of the filename, eg the first character?
Get-ChildItem -Force -Recurse | Rename-Item -NewName ($_.Name -replace "^ ","_")
Your post title doesn't quite line up with what you're asking.
There's also a syntax error in your example code (you're missing the period when trying to access the Name property of the PSItem $_).
None the less I hope this is what you're looking for. You were mostly there. The first parameter of -replace interprets regex.

rename multiple pdf files thru CMD

Have 2500 pdf files in a folder with fixed length name with a delimiter " _ "
200422028240000148_8393929.pdf
742022028240000014_4366273.pdf
Need to rename with first name available before the delimiter
200422028240000148.pdf
742022028240000014.pdf
How can i do with CMD as well powershell without currupting file and also cant use external utility or tool this being production server
This is really basic PowerShell.
Please, take some time to lookup the workings of Get-ChildItem and Rename-Item to figure out how below code works:
Get-ChildItem -Path 'X:\TheFolder' -Filter '*.pdf' -File | Rename-Item -NewName {
($_.BaseName -split '_')[0] + $_.Extension
}

Removing multiple consecutive periods from file names

I am working on cleaning up a file share for a SharePoint migration, and I am writing a script to either remove or replace unwanted characters from file names. I am struggling to remove multiple consecutive periods (file..example.txt as an example of what I am dealing with).
I was able to use the simple replace script below to deal with all of the other objectionable characters, but the script fails when attempting to replace double period errors.
dir -recurse | rename-item -NewName {$_.name -replace ".." , ""}
I expect that a file with a name like file..example.txt to become fileexample.txt, however nothing changes.
As Matt mentioned in the comments, -replace uses regex. In regex, the . character is a wildcard representing any single character. To actually select a dot, you must use \..
The regex for selecting anything with two or more dots is \.\.+ (RegExr)
Therefore, your command should be:
dir -Recurse | Rename-Item -NewName {$_.name -replace "\.\.+" , ""}
However, dir is an alias for Get-ChildItem. It's a good practice when writing scripts to avoid aliases whenever possible as it can create a situation where your script does not work in certain environments. With that in mind, your command should be:
Get-ChildItem -Recurse | Rename-Item -NewName {$_.name -replace "\.\.+" , ""}
You can use .replace() instead, and not have to worry about the regex. Note that Rename-Item is using a delay bind script block https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parameters?view=powershell-5.1
Get-Childitem -Recurse -Filter *..* |
Rename-Item -NewName { $_.Name.Replace('..','.') } -WhatIf

Powershell replace characters in files within sub-directories using -LiteralPath

I want to replace bad characters in filenames within all sub-directories. However due to limitation of rename-item with '[' (wild cards) I have to use the
-LiteralPath in the command. This means I'm having issues with running this with sub-directories.
The code below works on current directory, but I cannot work out how to adapt this code to rename files within all sub-directories. Please help?
ls *.* -recurse | % { Move-Item -literalpath $_.fullname `
($_.name -replace "[()\[\]]|\.(?!\w{3}$)", " ") }
Your RegEx will remove the dot's from extensions with not exactly 3 chars.
.h
.cs
.html
I suggest replacing in BaseName and append the extension and only if brackets/parentheses/dots chars are present.
Get-ChildItem *.* -Recurse -File|
Where-Object {$_.BaseName -match '[()\[\]\.]'}|
Rename-Item -NewName {($_.BaseName -replace '[()\[\]\.]',' ')+$_.Extension} -Whatif
Remove the -WhatIf if the output looks OK.