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

I have a report file that is generated and contains various file links. I use Select-String and regular expressions to match certain types of files and subsequently process them.

The dilemma that I have is trying to sequentially identify the number of matches when zeros (0), one (1), or more than one (2+) match. Here is what I tried:

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

This returns "null" if there are 0 matches, "1" if they match, and "null" if there are multiple matches.

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

this returns "null" if there is a 0 or 1 match and the number of matches if more than one match.


I am unsuccessfully new to Powershell, but trying to find a consistent way to check the number of matches, regardless of whether there are 0, 1, or more than 1 matches.

+4
source share
2 answers

Try the following:

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

Powershell has a number of comparison operators that are likely to make your life easier. Here is a quick list:

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

In this case, -Match will match the string $ content for your regular expression $ regex, and the result is grouped in parentheses. This grouping is a collection of strings. Then we can count the objects and print the exact number of matches.

So why is your code working as expected? When you have one match, .Matches actually returns a System.Text.RegularExpressions.Match object, which looks something like this for the string "test123":

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

Why is this happening? Because the Microsoft.PowerShell.Commands.MatchInfo object returns a Select-String . You can verify this by doing some other properties, such as .Filename in the output with a single match.

Ok, but why can't we get all our matches at once? This is because multiple matches return multiple objects, so now you have a collection in which you are trying to work. The collection is of a different type and does not understand .Matches . No collection is returned in 1 match, but instead there is one object that understands .Matches !

In short: these are not the results you are looking for!

+6
source

You can use the @(...) array sub-expression operator to place the results in the collection using 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 
+2
source

Source: https://habr.com/ru/post/1500613/


All Articles