Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Powershell: replace every line that contains a given string

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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!

>Solution :

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'
    
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading