簡體   English   中英

Powershell - 正則表達式匹配文件中的多行

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM