Suppose I have a text file that contains the following lines:
Apple
Bananas
Fruit things
Oranges
Fruit pieces
I want to replace every line that contains the string "Fruit" with a new line that contains just the string "MoreSpecific". I've worked out the following code:
$File = '\path\to\file.txt'
$Locate = Get-Content $File | Select-String "Fruit" | Select-Object -ExpandProperty Line
(Get-Content $File) | ForEach-Object {$_ -replace "$Locate","MoreSpecific"} | Set-Content $File
...but nothing in the target files is replaced. Running echo $Locate
gives the following output:
Fruit things
Fruit pieces
...indicating that both complete lines are being stored in the variable. Now it makes sense, because since no single line contains the entirety of the two lines together, no match is found and no replacement is made. Sure enough, if I remove the second line containing "Fruit", the single remaining line is replaced.
What I need is to perform the line replacement immediately upon finding the matching string, before proceeding to the next match. Advice appreciated!
If I understand correctly you can simplify it a lot:
@'
Apple
Bananas
Fruit things
Oranges
Fruit pieces
'@ -replace 'Fruit.+', 'More specific'
Applied to your code:
(Get-Content $File -Raw) -replace 'Fruit.+', 'More specific' |
Set-Content $File
If casing is important (if you need to match Fruit
with an uppercase F
) use -creplace
instead of -replace
.
If Fruit
(the keyword) isn't always starting the line and you still want to replace the whole line, the regex should be .*Fruit.*
:
(Get-Content $File -Raw) -replace '.*Fruit.*', 'More specific'