2

I was looking for a way adjust the following:

  • Name S01e01.mp4
  • Name s01e02.mp4
  • Name s01e03.mp4

Is there a way to capitalize the S and E ??

  • Name S01E01.mp4
  • Name S01E02.mp4
  • Name S01E03.mp4

I have tried the below but it replaces all E's resulting in:

dir -recurse | where {-Not $_.PsIscontainer -AND $_.name -match "."} | 
foreach {
$New=$_.Basename.Replace(" s"," S").Replace("e","E")+$_.Extension
Rename-Item -path $_.Fullname -newname $New -passthru
}
  • NamE S01E01.mp4
  • NamE S01E02.mp4
  • NamE S01E03.mp4

Thank you so much in advance.

UPDATE:

cd C:\Users\test\Desktop\test
PS C:\Users\test\Desktop\test> dir -recurse | where {-Not $_.PsIscontainer -AND $_.name -match "."} |
>> foreach {
>> $New = $_.Name -replace '(.* )s(\d{2})e(\d{2}\..*)', '$1S$2E$3'
>> Rename-Item -path $_.Fullname -newname $New -passthru
>> }


    Directory: C:\Users\test\Desktop\test


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        1/25/2018   2:32 PM              0 Test.Of.Testing.S01e01.this.X264.Mp4
-a----        1/25/2018   2:32 PM              0 Test.Of.Testing.S01E01.this.X264.Mp4
-a----        1/25/2018   2:33 PM              0 Test.Of.Testing.S01e31.this.X264.Mp4
-a----        1/25/2018   2:33 PM              0 Test.Of.Testing.s01E01.this.X264.Mp4

This is what I currently get after swapping in the suggestion from mklement0, it almost looks like nothing changes?

Thanks

Defca Trick
  • 315
  • 1
  • 5
  • 18

1 Answers1

1

Your approach didn't work, because the [string] type's .Replace() method invariably replaces all (literal) matches.

Instead, use PowerShell's -replace operator, which is regex-based (using a single file name as an example):

> 'Name s01e01.mp4' -replace '(.*\b)s(\d{2})e(\d{2}\b.*)', '$1S$2E$3'
Name S01E01.mp4

For a concise summary of -replace's behavior, see this answer of mine.

Note:

  • For simplicity, the regex above is designed to match the entire filename, including extension; in the context of the code posted in the question the line therefore needs to be:
    $New = $_.Name -replace '(.*\b)s(\d{2})e(\d{2}\b.*)', '$1S$2E$3'

  • -replace is the same as -ireplace; that is, matching is case-insensitive. Thus, if both the s and the e in question already are uppercased, the replacement is an effective no-op; however, if either or both are lowercased, the replacement ensures that they are uppercased.


To put it all together, using PSv3+ syntax:

Get-ChildItem *.* -Recurse -File |
  Rename-Item -NewName { $_.Name -replace '(.*\b)s(\d{2})e(\d{2}\b.*)', '$1S$2E$3' } 

Note:

  • The PSv3+ -File switch makes Get-ChildItem return files only (similarly, you can ask for directories only with -Directory).

  • *.* as the (implied) -Path argument only matches filenames that contain at least one period (.), which I presume was your intent; by contrast, your attempt to do the same with -match '.' would have matched all filenames, because metacharacter . in a regex represents any single char.

    • On a side note: passing *.* to the -Filter rather than to the -Path argument also matches all filenames, because it is then the Windows API that interprets the wildcard expression, not PowerShell, and for backward-compatibility reasons *.* is treated the same as *.
  • There is no need for a foreach (ForEach-Object) loop, because Rename-Item can accept Get-ChildItem's output directly.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • im importing the string from file names, so the S00E00 will change, is there a way to just seperate the string or tell my powershell script to ignore capitalization when it runs? – Defca Trick Jan 26 '18 at 04:27
  • What, specifically, will change? The current answer matches any 2-digit sequences with `\d{2}`. I don't know what you mean by your 2nd sentence. – mklement0 Jan 26 '18 at 04:30
  • When i use your line in place of my $New it removes the extension and doesnt change anything, so I guess im not sure how to incorporate your line into my existing code above. – Defca Trick Jan 26 '18 at 04:45
  • @DefcaTrick: Please see my update. The previous regex didn't work, because you quietly changed the premise of the question: your original sample filename had a _space_ before the `s\d{2}e\d{2}` substring, whereas the filenames in the sample command you added later had a _period_. I've generalized the regex to now match at _word boundaries_ with `\b`, which should cover both cases. Please note that it is important to provide _representative_ sample input, including a description of the variations that can occur. Finally, see the simplified version of your overall command at the bottom. – mklement0 Jan 27 '18 at 13:54