select-string,搜索一个值,如果找到则搜索一秒钟如果两者都找到,则存储结果

问题描述

我试图找出文本文件中何时存在一系列值。搜索值一将始终比搜索值二高出至少一行。但是,它可能向下 20 行,或者根本不存在。

我尝试的每个版本的正则表达式都会为变量返回一个空值,因为它在两行中都不存在。我尝试使用上下文,但这只会带回单个搜索的记录,我无法在其中进行子搜索。我很感激任何帮助。值 1 是“检查:全部”。值 2 是“净总计”

$path = "C:\TEMP\generic.txt"

$try1 =  ( Get-Content $path | Out-String ).Trim() | select-string -Pattern "VALUE1:*.VALUE2 " -AllMatches |Select-Object -first 1 | Out-String 

$try2=  ( Get-Content $path -raw | Select-String -Pattern '(.*VALUE1\r\nVALUE2.*)' -AllMatches | select -expand Matches | select -expand Groups |  select -expand Value )#| Set-Content $outfile

解决方法

您需要像正在做的那样将其视为单个字符串,但是您的模式必须考虑两个值之间的所有字符。这可能包括多个换行/回车,因为行的数量各不相同。

你需要一个非贪婪的匹配。希望以下示例能回答您的问题。

首先,一个示例文件

$tempfile = New-TemporaryFile

@'
a line with value1 in it
some line
and another line
a line with value2 in it
a line
a line with value1 in it
some line
and another line
yet another line
a line with value2 in it
a line with value1 in it
some line
and another line
yet another line
too many lines
a line with value2 in it
'@ | Set-Content $tempfile

使用 Select-String

$text = Get-Content $tempfile -Raw

$pattern = '(?s)(value1).+?(value2)'

($text | Select-String -Pattern $pattern -AllMatches).Matches|ForEach-Object {
    "----- This is one match -----"
    $_.value
}

使用 .Net [regex]

$text = Get-Content $tempfile -Raw

$pattern = '(value1).+?(value2)'

[regex]::Matches($text,$pattern,16)|ForEach-Object {
    "----- This is one match -----"
    $_.value
}

两者的输出

----- This is one match -----
value1 in it
some line
and another line
a line with value2
----- This is one match -----
value1 in it
some line
and another line
yet another line
a line with value2
----- This is one match -----
value1 in it
some line
and another line
yet another line
too many lines

有趣的是,如果您使用 [regex] 并从 -Raw 中省略 Get-Content,它将去除新行/回车符并为您提供相同的文本,但在一行中。

----- This is one match -----
value1 in it some line and another line a line with value2
----- This is one match -----
value1 in it some line and another line yet another line a line with value2
----- This is one match -----
value1 in it some line and another line yet another line too many lines a line with value2