Powershell select-string returns different values depending on number of matches
Try this:
$content = Get-Content $outputfilePath($content -match $regex).Count
Powershell has a number of Comparison Operators that will probably make your life easier. Here's a quick listing:
-eq-ne-gt-ge -lt-le-Like-NotLike-Match-NotMatch-Contains-NotContains-In-NotIn-Replace
In this instance, -Match
will match the $content string against your regular expression $regex, and the output is grouped by parenthesis. This grouping is a collection of strings. We can then Count the objects and print out an accurate count of matches.
So why doesn't your code work as expected? When you have a single match, .Matches
actually returns a System.Text.RegularExpressions.Match object that looks something like this for a string "test123":
Groups : {test123}Success : TrueCaptures : {test123}Index : 15Length : 7Value : test123
Why does this happen? Because a Microsoft.PowerShell.Commands.MatchInfo object is what Select-String
returns. You can verify this by attempting some other properties like .Filename
on your single-match output.
Okay, but why can't we get all of our matches in one go? This is because multiple matches will return multiple objects, so now you have a collection that you're trying to operate on. The collection has a different type, and doesn't understand .Matches
. No collection is returned on 1 match, but instead a single object that does understand .Matches
is!
Long story short: these aren't the outputs you're looking for!
You can use the array sub-expression operator @(...)
to always place results in a collection with a 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