The -replace
operator operates on regexes (regular expressions), not wildcard expressons such as *
(by itself), which is what you're trying to use.
A conceptually more direct approach is to focus the replacement on the end of the string:
Get-ChildItem | # `dir` is a built-in alias for Get-ChildItem`
Rename-Item -NewName { $_.Name -replace '(?<=_)[^_]+(?=\.)', '00$&' } -WhatIf
Note: The -WhatIf
common parameter in the command above previews the operation. Remove -WhatIf
once you're sure the operation will do what you want.
(?<=_)[^_]+(?=\.)
matches a nonempty run (+
) of non-_
chars. ([^_]
) preceded by _
((?<=_
) and followed by a literal .
((?=\.)
), excluding both the preceding _
and the following .
from what is captured by the match ((?<=...)
and (?=...)
are non-capturing look-around assertions).
- In short: This matches and captures the characters after the last
_
and before the start of the filename extension.
00$&
replaces what was matched with 00
, followed by what the match captured ($&
).
In a follow-up comment you mention wanting to not just blindly insert 00
, but to 0
-left-pad the number after the last _
to 3 digits, whatever the number may be.
In PowerShell [Core] 6.1+, this can be achieved as follows:
Get-ChildItem |
Rename-Item -NewName {
$_.Name -replace '(?<=_)[^_]+(?=\.)', { $_.Value.PadLeft(3, '0') }
} -WhatIf
The script block ({ ... }
) as the replacement operand receives each match as a Match
instance stored in automatic variable $_
, whose .Value
property contains the captured text.
Calling .PadLeft(3, '0')
on that captured text 0
-left-pads it to 3 digits and outputs the result, which replaces the regex match at hand.
A quick demonstration:
PS> 'PRT14_WD_14220000_1.jpg' -replace '(?<=_)[^_]+(?=\.)', { $_.Value.PadLeft(3, '0') }
PRT14_WD_14220000_001.jpg # Note how '_1.jpg' was replaced with '_001.jpg'
In earlier PowerShell versions, you must make direct use of the .NET [regex]
type's .Replace()
method, which fundamentally works the same:
Get-ChildItem |
Rename-Item -NewName {
[regex]::Replace($_.Name, '(?<=_)[^_]+(?=\.)', { param($m) $m.Value.PadLeft(3, '0') })
} -WhatIf