簡體   English   中英

如何使用 Powershell 從多行中選擇字符串

[英]How to Select-String from Multiple Lines with Powershell

我在 test.dat 下面有這個文件

        <category>Games</category>
</game>

        <category>Applications</category>
</game>

        <category>Demos</category>
</game>

        <category>Games</category>
        <description>MLB 2002 (USA)</description>
</game>

        <category>Bonus Discs</category>
</game>

        <category>Multimedia</category>
</game>

        <category>Add-Ons</category>
</game>

        <category>Educational</category>
</game>

        <category>Coverdiscs</category>
</game>

        <category>Video</category>
</game>

        <category>Audio</category>
</game>

        <category>Games</category>
</game>

如何使用Get-ContentSelect-String到 output 從上面的文件輸入到終端。 使用上面的輸入我需要接收這個 output。

            <category>Games</category>
    </game>
            <category>Games</category>
    </game>

這是我目前正在使用的命令,但它不起作用。 Get-Content '.\test.dat' | Select-String -pattern '(^\s+<category>Games<\/category>\n^\s+<\/game>$)'

首先,您需要將其全部作為一個字符串讀取以跨行匹配。

Get-Content '.\test.dat' -Raw

由於您似乎想排除條目,因此您可以使用此模式僅抓取那些前后沒有空格的條目

'(?s)\s+<category>Games\S+\r?\n</game>'

Select 字符串返回匹配信息 object 並且您需要提取Matches屬性的Value屬性。 你可以通過幾種不同的方式做到這一點。

Get-Content '.\test.dat' -Raw |
    Select-String '(?s)\s+<category>Games\S+\r?\n</game>' -AllMatches |
        ForEach-Object Matches | ForEach-Object Value

或者

$output = Get-Content '.\test.dat' -Raw |
    Select-String '(?s)\s+<category>Games\S+\r?\n</game>' -AllMatches

$output.Matches.Value

或者

(Get-Content '.\test.dat' -Raw |
    Select-String '(?s)\s+<category>Games\S+\r?\n</game>' -AllMatches).Matches.Value

Output

        <category>Games</category>
</game>


        <category>Games</category>
</game>

您也可以使用[regex]類型的加速器。

$str = Get-Content '.\test.dat' -Raw

[regex]::Matches($str,'(?s)\s+<category>Games\S+\r?\n</game>').value

編輯

根據您的附加信息,我理解的方式是您要刪除任何空的游戲類別。 我們可以通過使用 here 字符串大大簡化這一點。

$pattern = @'
        <category>Games</category>
    </game>

'@

額外的空白行是為了捕獲最后的換行符。 你也可以這樣寫

$pattern = @'
        <category>Games</category>
    </game>\r?\n
'@

現在,如果我們對模式進行替換,您將看到我認為您對最終結果的期望。

(Get-Content $inputfile -Raw) -replace $pattern

要完成它,您只需將上述命令放在Set-Content命令中即可。 由於Get-Content命令包含在括號中,因此在寫入文件之前將其完全讀入 memory。

Set-Content -Path $inputfile -Value ((Get-Content $inputfile -Raw) -replace $pattern)

編輯 2

好吧,它似乎在 ISE 中有效,但在 powershell 控制台中無效。 如果你遇到同樣的事情,試試這個。

$pattern = '(?s)\s+<category>Games</category>\r?\n\s+</game>'

Set-Content -Path $inputfile -Value ((Get-Content $inputfile -Raw) -replace $pattern)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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