Home > Net >  Is there an elegant regex to grep a MAC address accounting for various delimiters?
Is there an elegant regex to grep a MAC address accounting for various delimiters?

Time:07-29

I will occasionally search aggregate logs files on my syslog server for a specific MAC address. Since each source uses a different format for MAC addresses, I usually use this command:

less syslog.log | grep -i -E '56[:-\.]?ea[:-\.]?b6[:-\.]?a6[:-\.]?82[:-\.]?5e'

Which will find the address regardless of the format or case (56eab6a6825e, 56ea.b6a6.825e, 56:ea:b6:a6:82:5e, 56-EA-B6-A6-82-5E).

I have this command saved in text file so I can just replace each hex pair with the relevant digits and paste it in, but is there an elegant way format my regex where I can have the whole address together? For example:

less syslog.log | grep -i -E '56eab6a6825e[:-\.]?(anywhereinthestring)'

I basically want to be more lazy when searching, but I don't understand lookarounds enough to know if they are applicable in this case. Is this even possible?

CodePudding user response:

Simply store the mac-address to search in a variable and use Bash's replace expanded value to generate the Regex for grep:

mac='56:ea:b6:a6:82:5e'; grep -iE "${mac//:/[:.-]?}"

CodePudding user response:

Here's a function that takes a MAC address—uppercase or lowercase, with or without punctuation—and constructs a regex from it. You can run it just like grep, with either a list of files or nothing to read from stdin.

grep-mac() {
    local mac="$1"
    local files=("${@:2}")

    # Strip punctuation from the input MAC.
    mac="${mac//[^[:alnum:]]}"
    # Create a regex by inserting `[:-\.]?` in between every two characters.
    local regex="${mac:0:2}$(sed -E 's/../[:-\\.]?\0/g' <<< "${mac:2}")"

    # Call `grep` with the regex and files we were passed.
    grep -iE "$regex" "${files[@]}"
}

Example usage:

❯ grep-mac 56:ea:b6:a6:82:5e syslog.log | less
❯ grep-mac 56EAB6A6825E syslog.log | less

You can put it in your ~/.bashrc if you want easy access.

CodePudding user response:

You can try this grep

$ grep -Ei '56[[:alnum:]:.-] 5e' <(less syslog.log)
  • Related