Search code examples
powershellfilenamesfile-rename

Powershell remove [ ] (brackets) and () parentheses from filenames


I receive files from a source that places "[]" and "()" in the filenames. I wrote a script that removes other characters (spaces and commas, etc...) and it does great on them, but it will not remove these characters and causes the rest of the script to fail if any of the files have these characters.

$directory = "D:\files"

$files = Get-ChildItem -Path $directory

foreach ($file in $files) {
    $newName = $file.Name -replace " ", "."
    Rename-Item -Path $file.FullName -NewName $newName
}

foreach ($file in $files) {
    $newName = $file.Name -replace "\[", " "
    Rename-Item -Path $file.FullName -NewName $newName
}

I even found a source online that said to lead it with a backslash but that does not work either.

I would prefer to create a script to remove them all and replace them with a period unless they are found at the beginning of the filename.

Any help would be greatly appreciated.


Solution

  • You can simplify your code as follows:

    Get-ChildItem -LiteralPath $directory |
      Rename-Item -NewName { $_.Name -replace '[][() ]', '.' -replace '^\.' }
    
    • Your primary problem was the use of -Path instead of -LiteralPath: the former interprets a path as a wildcard expression, where [ and ] have special meaning, the latter does not.

    • The above implicitly binds to Rename-Item's -LiteralPath parameter, by directly providing file-information objects via the pipeline.

    • Note the use of a delay-bind script block ({ ... }) with the -NewName parameter, which allows you to determine the new name dynamically, for each pipeline input object, reflected in the automatic $_ variable.

    • The first regex used with the -replace operator replaces spaces, (, ), [ and ] characters with ., and the second one removes a . from the start of the resulting name, should there be one.

    Note that there's a possibility that renames may fail, if they result in duplicate file names.