regular expression for MAC address validation

Hi there

I am running a script which requires the input of a MAC address from the user and was loooking for a regex that will verify the user has inputted a full 12 digit valid MAC with colons

Ive seen a few on some sites that look huge and was wondering if anybody had a one liner (or as close as possible)

Any help would be greatly appreciated
Gary

echo 00:60:08:C4:99:AA | sed "/^\([0-9A-Z][0-9A-Z]:\)\{5\}[0-9A-Z][0-9A-Z]$/p"

I suppose the default output should be supressed,

echo 00:60:08:C4:99:AA | sed -n "/^\([0-9A-Z][0-9A-Z]:\)\{5\}[0-9A-Z][0-9A-Z]$/p"

You are right. I forgot to add that option.

thats fantastic, I dont suppose you have one for IP addresses too do you ??

#! /opt/third-party/bin/perl

my $ip = "a10.2.45.23";

if( $ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ ) {
  print "Match\n";
}
else {
  print "No Match\n";
}

exit 0

Not extensive though! :slight_smile:

echo 190.04.50.00 | awk -F"\." ' $0 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}$/ && $1 <=255 && $2 <= 255 && $3 <= 255 && $4 <= 255 '

not quite though. if user enters 256.256.256.256, it will still match, while in practice, this ip is invalid. somehow have to add a range from 0-255.

and this,

#! /opt/third-party/bin/perl

my $ip = "10.256.45.23";

my $no = 1;
if( $ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ ) {
  my @split_arr = split(/\./, $ip);
  foreach my $var (@split_arr) {
    if( $var > 255 ) {
      $no = 0;
      last;
    }
  }
  if ( $no ) {
    print "Match\n";
  }
  else {
    print "No Match\n";
  }
}
else {
  print "No Match\n";
}

exit 0

Thanks for your responses, I know this may be a simple question but how do i get my variable (read in by my script) ie ....

echo "Please enter your mac address now with colons"
read MAC

to be validated against the regex ??

do I use an if statement, ie .....

if [ $MAC=regex ] then
proceed
else
ERROR
fi

Is anything like that possible ???

if you use the sed solution: an eg

result=`var=`echo 00:60:08:C4:99:@ | sed -n "/^\([0-9A-Z][0-9A-Z]:\)\{5\}[0-9A-Z][0-9A-Z]$/p"``
if [ -z $result ]; then
    ....
fi

-z checks for empty string

You cannot really use nested backticks! :slight_smile:

use this,

result=$( echo 00:60:08:C4:99:12 | sed -n "/^\([0-9A-Z][0-9A-Z]:\)\{5\}[0-9A-Z][0-9A-Z]$/p" )
if [ -z $result ]; then
  echo $result
fi

sorry typo.

linux:/home # result=`echo 00:60:08:C4:99:AA | sed -n "/^\([0-9A-Z][0-9A-Z]:\)\{5\}[0-9A-Z][0-9A-Z]$/p"`
linux:/home# echo $result
00:60:08:C4:99:AA

ok so my script looks like this

echo enter mac
read mac
result=$( echo $mac | sed -n "/^\([0-9A-Z][0-9A-Z]:\)\{5\}[0-9A-Z][0-9A-Z]$/p" )
if [ -z $result ]; then
  echo mac doesnt comply
else
  echo mac is fine
fi

but when i run it, whatever I put in, valid or not, it comes back with the same answer

[root@my-server] # ./test-mac.sh
enter mac
00:60:08:C4:99:44
mac doesnt comply

or ...

[root@my-server] # ./test-mac.sh
enter mac
sausages
mac doesnt comply

is there something im missing

mine is ok, even with backticks.

make sure you have no leading/trailing 'spaces' once you do your 'data entry' - you're anchoring at the beginning and at the end of your 'entered' string.

ive typed it in manually still no good (no spaces at beginning or end).....my script again is ....

#!/bin/ksh
echo enter mac
read mac
result=$( echo $mac | sed -n "/^\([0-9A-Z][0-9A-Z]:\)\{5\}[0-9A-Z][0-9A-Z]$/p" )
if [ -z $result ]; then
  echo mac doesnt comply
else
echo mac is fine
fi

Just out of interest if i run the command that was posted earlier at the command line

echo 00:60:08:C4:99:AA | sed -n "/^\([0-9A-Z][0-9A-Z]:\)\{5\}[0-9A-Z][0-9A-Z]$/p"

i get no output at all ...is this what is expected? ....if i remove the -n at just outputs what ever mac address i put in the begginning of the command (even if its invalid) ie....

bash # echo sausages | sed "/^\([0-9A-Z][0-9A-Z]:\)\{5\}[0-9A-Z][0-9A-Z]$/p"
bash # sausages
bash #

surely that isnt supposed to happen is it ??

OK this works perfectly (using egrep rather than sed)

#!/bin/ksh
echo enter mac
read mac
result=$( echo $mac | egrep ^[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]$ )
if [ -z $result ]; then
  echo mac doesnt comply
else
echo mac is fine
fi

You should get the following output

$ echo 00:60:08:C4:99:AA | sed -n "/^\([0-9A-Z][0-9A-Z]:\)\{5\}[0-9A-Z][0-9A-Z]$/p"
00:60:08:C4:99:AA

-n option prevents the default output i.e whatever the string processed by the sed command

This is correct.

This was wrong actually as said to ghostdog

check this thread