Cannot remove text between two strings with ReadLines

Viewed 64

test.txt contents:

foo

[HKEY_USERS\S-1-5-18\Software\Microsoft]

bar

delete me!

[HKEY_other_key]

end-------------

Online regex matches the text to be removed correctly (starting from string delete until string [HKEY), but code written in PowerShell doesn't remove anything when I run it in PowerShell ISE:

$file = [System.IO.File]::ReadLines("test.txt")
$pattern = $("(?sm)^delete.*?(?=^\[HKEY)")
$file -replace $pattern, "" # returns original test.txt including line "delete me!" which should be removed

It seems to be a problem with ReadLines because when I use alternative Get-Content:

$file = Get-Content -Path test.txt -Raw

it removes the unwanted line correctly, but I don't want to use Get-Content.

1 Answers

[System.IO.File]::ReadAllLines(..) reads all lines of the file into a string array and you're using a multi-line regex pattern.

Get-Content -Raw same as [System.IO.File]::ReadAllText(..), reads all the text in the file into a string.

[System.IO.File]::ReadAllText("$pwd\test.txt") -replace "(?sm)^delete.*?(?=^\[HKEY)"

Results in:

foo

[HKEY_USERS\S-1-5-18\Software\Microsoft]

bar

[HKEY_other_key]

end-------------

In case you do need to read the file line-by-line due to, for example, high memory consumption, switch -File is an excellent built-in PowerShell alternative:

switch -Regex -File('test.txt') {
    '^delete' {        # if starts with `delete`
        $skip = $true  # set this var to `$true
        continue       # go to next line
    }
    '^\[HKEY' {        # if starts with `[HKEY`
        $skip = $false # set this var to `$false`
        $_             # output this line
        continue       # go to next line
    }
    { $skip } { continue } # if this var is `$true`, go next line
    Default   { $_ }       # if none of the previous conditions were met, ouput this line
}
Related