微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 Powershell 从多行中选择字符串

如何解决如何使用 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 将以下内容从上述文件的输入输出到终端。使用上述输入,我需要接收此输出

            <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>'

选择字符串返回一个匹配信息对象,您需要提取 Value 属性的 Matches 属性。您可以通过几种不同的方式做到这一点。

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

输出

        <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 命令被括在括号中,因此在写入文件之前将其完全读入内存。

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)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。