2

I am using Get-Content (gc) here. I need to delete a set of lines defined by the start and end marker. But for some reasons, the command that I use does not work. Do you know what I am missing here?

Command that I have tried:

powershell -Command ((gc test.txt) -replace '"/\#start.*\#end/gms"','')

test.txt:

line1
line2
#start
line3
line4
#end
line5

Expected output:

line1
line2
line5
Gerhard
  • 22,678
  • 7
  • 27
  • 43
Balaji Vignesh
  • 446
  • 1
  • 7
  • 19

2 Answers2

3

Get-Content reads the file into an Array of strings. Use Get-Content -Raw to read it as one string.

powershell -Command ((Get-Content -Path test.txt -Raw) -replace '(?smi)#start(.*)#end\r?\n','')
TobyU
  • 3,718
  • 2
  • 21
  • 32
2

As answered by @TobyU, using the -Raw will easily resolve the issue but there is a downside to this quick solution:

PowerShell is extremely good in streaming objects, that's why Get-Content supplies a stream of lines in the first place. If you use the -Raw and/or brackets, you choke the output pipeline. This is not a big issue for a small list but could cause performance issues and/or memory issues when the list gets larger.

In respect of the PowerShell streaming pipeline you might consider to resolve it like this:

$On = $True; Get-Content -Path test.txt | Where {If ($_ -eq '#start') {$On = $False} ElseIf ($_ -eq '#end') {$On = $True} Else {$On}}

In this command, Where filters the #Start and #End as it has in both cases no output at all and passes the rest of the lines when $on is $True.

iRon
  • 20,463
  • 10
  • 53
  • 79