views:

327

answers:

3

I have a list of files like this:
Test.(file1)[text].txt
Test.(file2)[text].txt
Test.(file3)[text].txt

I need to remove any "()","[]" and any ".", replace them spaces without changing the file extension. I've tried the following but it's not working:

dir C:\scratch\*.txt | % { Rename-Item $_ ($_.basename -replace "\(", " "`
   -replace "\)", " "`
   -replace "\[", " "`
   -replace "\]", " "`
   -replace ".", " ")}

Ideally the file name should end up in the format "Test file1 text.txt"

+4  A: 

Rename-Item doesn't work with files that contain "[" or "]". This is a known issue.

It turns out that the problem is because Rename-Item is missing a -LiteralPath parameter. Move-Item has this parameter, so you can use it to do what you want:

ls C:\scratch\*.txt | 
    % { Move-Item -literalpath $_.fullname `
        ($_.name -replace "[()\[\]]|\.(?!\w{3}$)", " ") -whatif }

Remove the -WhatIf parameter when it looks like it is doing what you want it to do. My regular expression leaves files like "Test  file1  text.txt", which isn't quite what you wanted.

Jeff Hillman
+4  A: 

IMO Rename-Item appears to be broken in terms of its handling of paths with [ ] chars in them. Fortunately, Move-Item works:

dir *.txt | 
    mi -dest {($_.Basename -replace '[()[\].]+',' ').Trim() + $_.Extension}

Where mi is the alias for Move-Item. Note that a number of cmdlets like Rename-Item and Move-Item can be piped to directly and then their NewName/Destination parameters can take scriptblocks in which you can use the pipeline object. Internally this works for pipeline bound parameters as PowerShell will execute the scriptblock and attempt to coerce the result to the type expected by the parameter.

Keith Hill
Both answers work fine, I gave the answer to this one because of the easier regex. One question though: running the above would leave two spaces where there might be adjacent characters together. Would I need to add another -replace '\s+', ''? And how would I replace the space at the end of the string? \z doesn't seem to do it.
fenster
See the updated regex in the answer: [()[\].]-->+<-- and the addtion of Trim().
Keith Hill
A: 

If you do not need to do it programatically, use http://www.bulkrenameutility.co.uk/Screenshots.php instead. I have been using this for years to rename images, and a bunch of other things!

Mitchell Skurnik