4

我有一个生成的报告文件,其中包含各种文件引用。我正在使用 Select-String 和正则表达式来匹配某些类型的文件并对其执行后续处理。

我遇到的困境是试图在有零 (0)、一 (1) 或多于一 (2+) 匹配时始终识别匹配的数量。这是我尝试过的:

(select-string -path $outputfilePath -pattern $regex -allmatches).matches.count

如果有 0 个匹配项,则返回“null”,如果有一个匹配项,则返回“1”,如果有多个匹配项,则返回“null”。

(select-string -path $outputfilePath -pattern $regex -allmatches).count

如果有 0 个或 1 个匹配项,则返回“null”,如果有多个匹配项,则返回匹配项数。


我是 Powershell 的新手,但我试图找到一种一致的方法来测试匹配的数量,无论是否有 0、1 或超过 1 个匹配。

4

2 回答 2

6

尝试这个:

$content = Get-Content $outputfilePath
($content -match $regex).Count

Powershell 有许多比较运算符它们可能会让您的生活更轻松。这是一个快速列表:

-eq
-ne
-gt
-ge   
-lt
-le
-Like
-NotLike
-Match
-NotMatch
-Contains
-NotContains
-In
-NotIn
-Replace

在这种情况下,-Match会将 $content 字符串与您的正则表达式 $regex 进行匹配,并且输出按括号分组。该分组是字符串的集合。然后我们可以对对象进行计数并打印出准确的匹配计数。

那么为什么你的代码没有按预期工作呢?当您有一个匹配项时,.Matches实际上返回一个System.Text.RegularExpressions.Match对象,对于字符串“test123”,它看起来像这样:

Groups   : {test123}
Success  : True
Captures : {test123}
Index    : 15
Length   : 7
Value    : test123

为什么会这样?因为返回的是Microsoft.PowerShell.Commands.MatchInfo对象Select-String。您可以通过尝试其他一些属性来验证这一点,例如.Filename在单匹配输出上。

好的,但是为什么我们不能一次完成所有的比赛呢?这是因为多个匹配将返回多个对象,所以现在您有一个要操作的集合。该集合具有不同的类型,并且不理解.Matches。1 个匹配项没有返回集合,而是一个可以理解.Matches的对象!

长话短说:这些不是您要寻找的输出!

于 2013-09-04T20:50:12.273 回答
2

您可以使用数组子表达式运算符@(...)始终将结果放在带有 的集合中Count

(Select-String ...)        # may return $null, one match, or a collection of matches
(Select-String ...).Count  # only succeeds for two or more matches

@(Select-String ...)       # always returns a collection of matches
@(Select-String ...).Count # always succeeds
于 2013-09-06T23:53:06.130 回答