Search code examples
regexpowershellfile-renamelowercaserename-item-cmdlet

How to Change case of part of Filename with Powershell and Regex?


Have a bunch of Video files, that all contain either 1080P / 720P in the end of Base Filename but before the Extension usually, but we can assume all the filenames have either one of two anywhere in the Basename.

Now I wanna rename file such that only the case of that specific string changes, means only either 1080P becomes 1080p or 720P becomes 720p.

I already tried with this code, but it doesn't do a damn thing:

$validExts = '.mkv', '.mp4', '.mov', '.avi', '.wmv', '.webm', '.avchd', '.flv'
Get-ChildItem -File |
    Where-Object Extension -In $validExts |
    Where-Object Length -Gt 500mb |
    Rename-Item -NewName {
        ($_.BaseName -replace '^.*(1080P|720P)$', $_.Value.ToLower())
    }
### Also tried with ^.*(1080P|720P).*$, but doesn't work either
### Even if I put it like this `...{$_.Value.ToLower()}`, 
###  it only produces unexpected weird results like 
###  "ISLAND OF THE DOLLS 2023 ENGLISH 1080P.Value.ToLower()"

Example: Input: ISLAND OF THE DOLLS 2023 ENGLISH 1080P.mkv Output: ISLAND OF THE DOLLS 2023 ENGLISH 1080p.mkv


Solution

  • Seems like in your code you wanted to use replacement with a scriptblock but in this case is not really needed, what you can do instead is add an additional filter to get only those files that actually have the uppercase P, then you can use the automatic $Matches variable for the replacement:

    $validExts = '.mkv', '.mp4', '.mov', '.avi', '.wmv', '.webm', '.avchd', '.flv'
    Get-ChildItem -File |
        Where-Object Extension -In $validExts |
        Where-Object Length -GT 500mb |
        Where-Object Name -CMatch '(?:1080|720)P' | # if there is a match here it gets stored in `$Matches`
        Rename-Item -NewName { $_.Name.Replace($Matches[0], $Matches[0].ToLower()) }