Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell select-string returns different values depending on number of matches

I have a report file that is generated and containes various file references. I am using Select-String and regular expressions to match on certain types of files and perform subsequent processing on them.

the dilemma I have is trying to consistently identify the number of matches when there are zero (0), one (1), or more than one (2+) matches. Here is what I've tried:

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

This return "null" if there are 0 matches, "1" if one match, and "null" if more than one match.

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

this return "null" if there are 0 or 1 match and the number of matches if more than one match.


I'm faily new to Powershell, but am trying to find a consistent way to test on the number of matches regardless of whether there are 0, 1, or more than 1 match.

like image 348
user2748431 Avatar asked Feb 15 '23 09:02

user2748431


1 Answers

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  : True
Captures : {test123}
Index    : 15
Length   : 7
Value    : 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!

like image 174
Anthony Neace Avatar answered May 12 '23 07:05

Anthony Neace