[英]Powershell - Regex match multiple lines from file
如果文本字符串是 powsershell 腳本的一部分,我可以匹配和替換多行:
$regex = @"
(?s)(--match from here--.*?
--up to here--)
"@
$text = @"
first line
--match from here--
other lines
--up to here--
last line
"@
$editedText = ($text -replace $regex, "")
$editedText | Set-Content ".\output.txt"
output.txt:
first line
last line
但是,如果我改為使用 Get-Content -Raw 從文件中讀取文本,則相同的正則表達式無法匹配任何內容。
$text = Get-Content ".\input.txt" -Raw
輸入.txt:
first line
--match from here--
other lines
--up to here--
last line
output.txt:
first line
--match from here--
other lines
--up to here--
last line
為什么是這樣? 我該怎么做才能匹配從 input.txt 讀入的文本? 提前致謝!
使用 here-string 代碼取決於 .ps1 文件使用的換行符類型。 如果它與輸入文件使用的換行符不匹配,它將不起作用。
要刪除此依賴關系,請定義一個使用\r?\n
匹配各種換行符的 RegEx:
$regex = "(?s)(--match from here--.*?\r?\n--up to here--)"
$text = Get-Content "input.txt" -Raw
$editedText = $text -replace $regex, ""
$editedText | Set-Content ".\output.txt"
或者,您可以使用基於switch
的解決方案,因此您可以使用更簡單的 RegEx 模式:
$include = $true
& { switch -File 'input.txt' -RegEx {
'--match from here--' { $include = $false }
{ $include } { $_ } # Output line if $include equals $true
'--up to here--' { $include = $true }
}} | Set-Content 'output.txt'
switch -File
構造循環輸入文件的所有行並將每一行傳遞給匹配表達式。
當我們找到第一個模式時,我們將$include
標志設置為$false
,這會導致代碼跳過所有行,直到找到第二個模式之后,這會將$include
標志設置回$true
。
單獨寫入$_
會導致輸出當前行。
我們將 pipe 設置為Set-Content
以減少腳本的 memory 占用空間。 我們沒有將所有行讀取到 memory 中的變量中,而是使用流式處理方法,其中每個處理的行都立即傳遞給Set-Content
。 請注意,我們不能直接從switch
塊中 pipe,因此作為解決方法,我們將switch
包裝在腳本塊中( & {... }
創建並調用腳本塊)。
該想法已從此GitHub 評論中采用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.