7

I saw this Powershell statement in a recent Hanselminutes post -

cat test.txt | foreach-object {$null = $_ -match '<FancyPants>(?<x>.*)<.FancyPants>'; $matches.x} | sort | get-unique

I'm trying to learn Powershell at the moment and I think that I understand most of what is going on -

  • The statement loops through each line of 'test.txt' and runs a regex against the current line
  • All the results are collated and then sorted and duplicates removed

My understanding seems to fall down on this part of the statement -

$null = $_ -match '<FancyPants>(?<x>.*)<.FancyPants>'; $matches.x
  • What is the '$null = ' part of the code doing, I suspect this is to handle a scenario when no match is returned but I'm not sure how it works?
  • Is '$matches.x' returning the matches found?
ipr101
  • 24,096
  • 8
  • 59
  • 61

2 Answers2

8

Yes, the -match operator results in True or False; assigning to $null suppresses the output.

The (?<>) regex syntax creates a capture group. In this case it's creating a capture group called x for any characters between <FancyPants> and <.FancyPants>. $matches contains the match info for the last match. Capture groups can be referenced by $matches.CaptureGroupName.

Here is an example you can use to see what is in the $Matches variable.

'123 Main','456 Broadway'| foreach{$_; $null = $_ -match '(?<MyMatch>\d+)'; ($Matches| ft *)}

In this example you would use $Matches.MyMatch to reference the match.

Rynant
  • 23,153
  • 5
  • 57
  • 71
  • So `$matches.x` contains the matches for the current object, does PS automatically collate all of `$matches` result sets into one large result set? – ipr101 Aug 23 '11 at 13:28
  • @ipr101 No it only keeps the last match. I've updated my answer with an example you can use to see what is in the `$Matches` variable. – Rynant Aug 23 '11 at 13:35
5

'$null=...' is used to suppress the result of the comparison. You may have seen something similar, like:

command | Out-Null

In the above, the Out-Null cmdlet is used to suppress the output. In some cases you may see this as well:

[void] (...)

Basically, all examples do the same thing, ignoring the output. If you don't use one of the above the result is going to write back to the pipeline and you may get unexpected results from commands further down in the pipeline.

Shay Levy
  • 121,444
  • 32
  • 184
  • 206