4

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.

8

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.

  • 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] – Stéphane Chazelas Feb 8 '18 at 13:15
6
[[ $mac_address: =~ ^([[:xdigit:]]{2}:){6}$ ]]
  • 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 Jan 8 '18 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. – user1404316 Feb 8 '18 at 12:17
4

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
0

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.