4

What would be the most handy way to grab the mouse's mac address from the following output:

~ ➜ bt-device --list
Added devices:
Logitech K811 (00:1F:20:EB:06:E0)
Plattan ADV Wireless (5C:EB:68:1F:D1:62)
Bluetooth Mouse M336/M337/M535 (34:88:5D:3F:1B:88)

Is there something shorter than this:

bt-device --list | grep Mouse | sed -e 's/^.*(\(.*\))$/\1/'
34:88:5D:3F:1B:88

I'm looking for a syntax like:

bt-device --list | grep Mouse | xyztool '(' ')'
terdon
  • 242,166
  • Remove the grep and yours is as good a choice as the others. bt-device --list | sed -e 's/^.Mouse.((.*))$/\1/' you could set this as an alias or function in .bashrc if you use it frequently; or just export the regex as an env variable - thats pretty common for regexs for IP addresses, urls, etc. – Argonauts May 16 '16 at 06:17

3 Answers3

7

Use awk to match the line and split it into words separated by ( or ). Take the 2nd word $2, or preferably the next-to-last $(NF-1) if you might have parentheses in the device name:

awk -F '[()]' '/Mouse/{print $(NF-1)}'
meuh
  • 51,383
2

Using grep with PCRE (-P):

bt-device --list | grep -Po 'Mouse\s.*?\(\K[^)]+'
  • Mouse\s.*?\( will match Mouse in the line and then upto first (, \K will discard the match

  • [^)]+ will get us the desired portion i.e. characters upto the next )

Example:

$ cat file.txt
Added devices:
Logitech K811 (00:1F:20:EB:06:E0)
Plattan ADV Wireless (5C:EB:68:1F:D1:62)
Bluetooth Mouse M336/M337/M535 (34:88:5D:3F:1B:88)

$ grep -Po 'Mouse\s.*?\(\K[^)]+' file.txt
34:88:5D:3F:1B:88
heemayl
  • 56,300
0

A few more choices:

  1. Perl

    $ bt-device --list | perl -lne 'print $1 if /Mouse.*\((.*)\)/' file 
    34:88:5D:3F:1B:88
    

    In many tools that deal with regular expressions, parentheses (()) are used to capture the matched pattern in a way that can later be used. In Perl, the 1st such captured pattern is $1, the second $2 etc. Here, we are looking for a line that matches Mouse and then a string in parentheses. The contents of the parentheses are saved as $1 and are printed if the match was successful.

  2. grep + cut + tr

    $ bt-device --list grep Mouse | cut -d'(' -f2 | tr -d ')'
    34:88:5D:3F:1B:88
    

    Here, we use grep to find the relevant line(s), cut to print the second (-defined field (34:88:5D:3F:1B:88)) and tr to delete the trailing ).

  3. Just for fun, here's a solution with join:

    $ join -1 1 -2 2 -o 2.4 <(echo "Mouse (") <(bt-device --list) 2>/dev/null | tr -d '()'
    34:88:5D:3F:1B:88
    
terdon
  • 242,166