0
votes

I found similar commands to these online. I want to replace the parenthesis in my file names to either a space or empty string.

The files I'm trying to change look like the following:

Nehemiah (1).mp3
Nehemiah (2).mp3
Nehemiah (11).mp3

Really I'd like them too look like the following:

Nehemiah 01.mp3
Nehemiah 02.mp3
Nehemiah 11.mp3

Here are the scripts I've tried.

Dir | Rename-Item –NewName { $_.name –replace “(“,”” }
Dir *.mp3 | rename-item -newname {  $_.name  -replace " ("," "  }

Neither of these work.

Here is the error message I'm getting.

Rename-Item : The input to the script block for parameter 'NewName' failed. The regular expression pattern ( is not valid. At line:1 char:34 + Dir *.mp3 | rename-item -newname { $_.name -replace " ("," " } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (C:\Users...ehemiah (1).mp3:PSObject) [Rename-Item], Parameter ndingException + FullyQualifiedErrorId : ScriptBlockArgumentInvocationFailed,Microsoft.PowerShell.Commands.RenameItemCommand

3
-replace expects a regular expression pattern, you need to escape the (: -replace [regex]::Escape(" (")," "Mathias R. Jessen
Thanks Mathias, that fixed the problem. I was wondering if I needed to escape the parenthesis BUT I couldn't find a list of characters needing escaping and how to escape them online. None of the sites I went to listed the parenthesis.jacob p
Also, please pick one tag. Using Batch-File when there is no batch file code.user4317867

3 Answers

5
votes

As you have seen in the comments from Mathias R Jessen -replace supports regular expressions and you need to account for that. The static method Escape can help automatically escape regex meta characters in strings so that the can appear more readable and function as you see them.

I did manage to find this on MSDN that talks about the characters that are escaped using [regex]::escape():

Escapes a minimal set of characters (\, *, +, ?, |, {, [, (,), ^, $,., #, and white space) by replacing them with their escape codes. This instructs the regular expression engine to interpret these characters literally rather than as metacharacters.

However since you don't actually need to be using regex here I would suggest you use the string method .replace() as that will accomplish the same without the extra overhead.

Get-ChildItem "*.mp3" | Rename-Item -NewName {($_.name).Replace(" ("," ")}

Character padding changes things a little though. I would op for regex there since it is a lot easier that splitting strings and putting them back together.

Get-ChildItem "*.mp3" | 
    Where-Object{$_.name -match "\((\d+)\)"}
    Rename-Item -NewName {
        [regex]::Replace($_.Name,"\((\d+)\)",{param($match) ($match.Groups[1].Value).PadLeft(2,"0")})
    }

Thanks to PetSerAl for helping with this backreference replacement solution.

1
votes

I'm sure this can probably be done in a simpler manner, but it works for me.

[regex]$rxp = '\((\d+)\)'; gci | ?{$_.Name -match $rxp} | %{ ren $_.FullName ($_.name -replace $rxp, $matches[1].padLeft(2,'0')) }

Here's a breakdown:

# Define regex.  The outer parentheses are literal.  The inner are a
# capture group, capturing the track number in the filename.

[regex]$rxp = '\((\d+)\)'

# Get-ChildItems.  For each child item that matches the regex...

gci | ?{$_.Name -match $rxp} | %{

    # Rename the file, replacing the offending regex match with the match
    # obtained from the where-object selector (the ? block)

    ren $_.FullName ($_.name -replace $rxp, $matches[1].padLeft(2,'0'))
}

PowerShell doesn't make it easy to massage the data captured by a backreference. However, the -match operator populates a $matches array which can be manipulated more easily.

This makes it possible not only to remove the parentheses, but also to zero pad your single-digit numbers.

0
votes

Try this.

ls | Where {$_.FullName -match '(-)'} | Rename-Item -NewName { $_ -replace ("-","_") }

I'm listing every file in the directory that matches (contains) a dash - then I pipe that into Rename-Item with new-name replacing the - for an underscore _

PS: The bonus is, I can quickly put back the dash from the underscore.