user4681760
user4681760

Reputation:

PowerShell script to remove characters from files and folders

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

Answers (1)

Matt
Matt

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 -Whatifs 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

Related Questions