7

The user can write in my Bash script a mac address in the following way:

read -p "enter mac-address " mac-address

Now i want to check in an if-statement, if this mac-address matches with a "specific" format. i.e. it should be FF:FF:FF:FF:FF:FF and not FFFFFFFFFFFF. Also the length should be correct: 6x2.

4 Answers 4

14

The lazy way is just to run

if [[ $mac_address == ??:??:??:??:??:?? ]]; then echo Heureka; fi

but this doesn't check whether it's a hex string. So if this is important

if [[ $mac_address =~ ^[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]$ ]]; then echo Heureka; fi

might be better. The later can be shortened to

if [[ $mac_address =~ ^([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}$ ]]; then
    echo Heureka; 
fi

If the pattern matches I don't see a need to check for the correct length as well.

1
  • Note that [a-f] also matches on â, é (and many other characters) with bash and in most of today's locales. Better to use [[:xdigit:]] as you do for the last example, or [0-9abcdefABCDEF] Commented Feb 8, 2018 at 13:15
6
[[ $mac_address: =~ ^([[:xdigit:]]{2}:){6}$ ]]
2
  • 3
    That's almost too clever, the only thing that makes it work is somewhat easy to miss. I think you'd still need to anchor the start of the string.
    – ilkkachu
    Commented Jan 8, 2018 at 22:15
  • I would vote this up multiple times if I could. I didn't understand how it could work, didn't catch the trick until I pasted into an xterm to test, and started to replace $mac_address with a literal, then I saw it. Commented Feb 8, 2018 at 12:17
5

I changed the name of the variable so that it consisted of legal characters, then used the =~ test operator to compare the value to the extended regular expression matching: at the beginning of the string ^, "2 hex digits and a colon" 5 times, followed by 2 hex digits, ending the string $:

#!/bin/bash

read -p "enter mac-address " mac_address

if [[ $mac_address =~ ^([[:xdigit:]][[:xdigit:]]:){5}[[:xdigit:]][[:xdigit:]]$ ]]
then
  echo good
else
  echo bad
fi
1

With standard sh syntax (so would work with bash and any other POSIX compatible shell):

x='[[:xdigit:]]'
mac_pattern="$x$x:$x$x:$x$x:$x$x:$x$x:$x$x"

printf >&2 'Please enter a MAC address: '; read mac
case $mac in
  ($mac_pattern) echo OK;;
  (*) echo >&2 BAD;;
esac

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .