Extract MAC Address only from this text

Hi,

I want to extract the MAC address from this text:

srv-ad.organization.local (192.168.46.30) em 00:0c:ff:ed:8e:78 [ether] em eth6

I’ve tried to use .split(" ") and then Select-String ‘.:.:.:.:.:.’ but it leaves the MAC with two empty lines…
Any better idea?

Regular expressions

'srv-ad.organization.local (192.168.46.30) em 00:0c:ff:ed:8e:78 [ether] em eth6' -match '(([0-9a-f]{2}:){5}[0-9a-f]{2})'
$Matches[0]

Olaf Soyk,

It didn’t worked…
It shows the same text:

PS C:\> $MAC
srv-ad.organization.local (192.168.46.30) em 00:0c:ff:ec:8d:78 [ether] em eth6
PS C:\> $MAC -match '(([0-9a-f]{2}:){5}[0-9a-f]{2})'
srv-ad.organization.local (192.168.46.30) em 00:0c:ff:ec:8d:78 [ether] em eth6

What worked for me was this:

($MAC.split(" ") | Select-String '.*:.*:.*:.*:.*:.*').Line

hmmm … that’s strange … the match operator should at least produce a true or false. Did you try the code just like I posted it?

Olaf Soyk,

Sorry, it wasn’t working, but I started a new console and worked perfeclty! Thanks!

This worked for me using Olaf’s suggestion

$mac = ‘srv-ad.organization.local (192.168.46.30) em 00:0c:ff:ed:8e:78 [ether] em eth6’
$result = $mac -match ‘(([0-9a-f]{2}:){5}[0-9a-f]{2})’
$Matches[0]
$result

00:0c:ff:ed:8e:78
True

'srv-ad.organization.local (192.168.46.30) em 00:0c:ff:ed:8e:78 [ether] em eth6' | 
foreach { -split $_ } | select -index 3

00:0c:ff:ed:8e:78

Neat! :slight_smile: But this works even shorter …

(‘srv-ad.organization.local (192.168.46.30) em 00:0c:ff:ed:8e:78 [ether] em eth6’ -split ’ ')[3]

You can just do

-split string
. It splits on whitespace by default.

you mean like this, right?

(-split ‘srv-ad.organization.local (192.168.46.30) em 00:0c:ff:ed:8e:78 [ether] em eth6’)[3]

hmmm … that does not safe that much and is (at least for me) harder to read. But thanks anyway. :wink:

It is annoying that -split has to be in the front with no arguments, and in the back with a custom delimiter. Here’s a cut function I made, like the unix command. So you can just say “string | cut -f 3”:

function cut {
  param(
    [Parameter(ValueFromPipeline=$True)] [string]$inputobject,
    [string]$delimiter='\s+',
    [string[]]$field
  )

    process {
    if ($field -eq $null) { $inputobject -split $delimiter } else {
      ($inputobject -split $delimiter)[$field] }
  }
}

Simpler RegEx

'srv-ad.organization.local (192.168.46.30) em 00:0c:ff:ed:8e:78 [ether] em eth6' -match "\w\w:.*:\w\w"
$matches.values

Or the .Net way

[regex]::Match('srv-ad.organization.local (192.168.46.30) em 00:0c:ff:ed:8e:78 [ether] em eth6', "\w\w:.*:\w\w").value

Another way

$string = 'srv-ad.organization.local (192.168.46.30) em 00:0c:ff:ed:8e:78 [ether] em eth6'
$string -match '(\w{2}:)+\w{2}' ; $Matches[0]

Hmmm … call me picky but both of these approaches would even match “illegal” Mac addresses like “00:0c:ff:ed:8e:78:8e:78” or “00:0c:ff:ed:8y:78:xz:78” or “8y:78:xz:78”, right? :wink: :smiley:

You are right, it would. In context I saw no indication that it was user generated input, nor did I see request for content validation. I only saw request to pull the MAC from the string, which the regex accomplishes. If MAC format validation is required, then yes, it would be the more appropriate option.