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. 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.