Reputation: 315
I was looking for a way adjust the following:
Is there a way to capitalize the S and E ??
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
}
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
Upvotes: 2
Views: 745
Reputation: 437608
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.
*.*
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.
Upvotes: 1