Reputation: 419
I am wrote some code and the first time it worked fine. However, I've now replaced the files with new dummy files and I'm now getting the following:
MyTestFile.zip
is changed to MyTestFile_zip.zip_zip.zip
MyTestFile.prd
is changed to MyTestFile_prd.prd_prd.prd
Here's the code:
Get-ChildItem -Filter "*.prd" -Recurse | Rename-Item -NewName {$_.name -replace '.prd','_prd.prd'}
Get-ChildItem -Filter "*.zip" -Recurse | Rename-Item -NewName {$_.name -replace '.zip','_zip.zip'}
Got any ideas how I can avoid this problem?
Thanks
Upvotes: 2
Views: 488
Reputation: 891
Editor's note:
While this answer doesn't work for the specific question at hand, because it inserts an extraneous .
, it does show the use of [System.IO.Path]::ChangeExtension()
as a robust way to change a file's extension in general.
Alternatively use the .net method to change the file extension:
Get-ChildItem -Filter "*.prd" -Recurse | Rename-Item -NewName {[System.IO.Path]::ChangeExtension($_.name,"_prd.prd")}
Upvotes: 1
Reputation: 439912
The -replace
operator
Therefore, you must modify the regex that is the first operand for the replacement to work as intended:
$_.Name -replace '\.prd$','_prd.prd'
.
is escaped as \.
to make sure that -replace
treats it as a literal; without the \
, .
would match any character.
$
ensures that the expression is anchored to the end of the input, i.e., only matches at the end.
A more generic reformulation that covers both .prd
and .zip
:
$_.Name -replace '\.(prd|zip)$','_$1.$1'
See below for an explanation.
If we put this all together, we can get away with a single pipeline:
Get-ChildItem -File *.prd, *.zip -Recurse |
Rename-Item -NewName { $_.Name -replace '\.(prd|zip)$','_$1.$1' }
Use of regular expressions allows you to process more than one extension at a time, and also allow you to reference parts of what the regular expression matched (captured) through capture groups (parenthesized subexpressions) that you can reference as $1
(1st capture group, ...) in the replacement string
> @( 'example.zip', 'example.prd' ) -replace '\.(prd|zip)$','_$1.$1'
example_zip.zip
example_prd.prd
Note how $1
in the replacement string refers to whatever capture group (prd|zip)
captured, which is zip
for the first input, and prd
for the second.
Upvotes: 3