Reputation:
I am trying to recursively remove certain characters from files and folders using a PowerShell script. Below is the script that I have found, but it will only remove underscores from files, not folders. There are a few characters which will need to be removed, but I am fine with having a script for each character if need be. It does recursively change files in the folders, but no folders are 'fixed'.
Current PowerShell script:
'dir -Recurse | where {-not $_.PsIscontainer -AND $_.name -match "_"} | foreach {
$New = $_.name.Replace("_","")
Rename-Item -path $_.Fullname -newname $New -passthru
}'
Upvotes: 0
Views: 4121
Reputation: 46710
As pointed out in the comments the core of your issue is that you are excluding folders with the -Not $_.PsIscontainer
component of your Where
block.
dir -recurse | where {$_.name -match "_"} | ...
The second issue that you are having is most likely that since you are changing folder names the children you had previously inventoried with dir
/Get-ChildItem
would then have incorrect paths. One way to address this would be to process files first then folders.
$filesandfolders = Get-ChildItem -recurse | Where-Object {$_.name -match "_"}
$filesandfolders | Where-Object {!$_.PsIscontainer} | foreach {
$New=$_.name.Replace("_","")
Rename-Item -path $_.Fullname -newname $New -passthru -WhatIf
}
$filesandfolders | Where-Object {$_.PsIscontainer} | foreach {
$New=$_.name.Replace("_","")
Rename-Item -path $_.Fullname -newname $New -passthru -WhatIf
}
By no means the prettiest solution but it would work. It processes all the files first, then the folders. Remove the -Whatif
s when you are sure it would do what you expect
Other characters
You had mentioned there were other characters that you were looking to remove. That wouldn't be a tall order. You could be using regex for this so lets try that.
$characters = "._"
$regex = "[$([regex]::Escape($characters))]"
$filesandfolders = Get-ChildItem -recurse | Where-Object {$_.name -match $regex}
$filesandfolders | Where-Object {!$_.PsIscontainer} | foreach {
$New=$_.name -Replace $regex
Rename-Item -path $_.Fullname -newname $New -passthru -WhatIf
}
$filesandfolders | Where-Object {$_.PsIscontainer} | foreach {
$New=$_.name -Replace $regex
Rename-Item -path $_.Fullname -newname $New -passthru -WhatIf
}
That would remove all of the periods and underscores from those files and folders.
Not tested but you might even be able to get it down to these few lines
$characters = "._"
$regex = "[$([regex]::Escape($characters))]"
$filesandfolders = Get-ChildItem -recurse | Where-Object {$_.name -match $regex}
$filesandfolders | Where-Object {!$_.PsIscontainer} | Rename-Item -NewName ($_.name -Replace $regex) -PassThru -WhatIf
$filesandfolders | Where-Object {$_.PsIscontainer} | Rename-Item -NewName ($_.name -Replace $regex) -PassThru -WhatIf
Upvotes: 1