Need to be with regex? You can use awk to take only the field corresponding to the status, and pass the interface name as parameter of the command ip:
ip link show eth0 | awk '{print $9 }'
First, ip link show eth0 shows only the network interface you want:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether b8:27:eb:01:1e:5b brd ff:ff:ff:ff:ff:ff
Then the pipe (the character |) takes this output and switches to the next command, which in this case is the awk.
The awk separates the contents of each line into fields, by default separated by spaces. Thus, the ninth field ($9) is what contains the information you want. That’s why print $9 showcase:
UP
Only the above command also shows a blank line below the UP, since the second line does not have 9 fields (if separated by spaces, there are only four), and therefore the print $9 does not print anything (but the print by default puts a line break at the end, so the result is a blank line).
An alternative to avoid this blank line is to use grep to pick up only the lines they have eth0 and then do the awk with this line:
ip link show eth0 | grep eth0 | awk '{print $9 }'
With this he only prints UP, and does not print the second blank line.
Another alternative is to use head with the option -n 1 to bring only the first line (the one that has eth0), so I don’t need the grep:
ip link show eth0 | head -n 1 | awk '{print $9 }'
If you really want to use regex, you can use grep with the option -P (that enables syntax Perl Compatible - since by default bash does not support lookbehind):
ip link show eth0 | head -n 1 | grep -o -P "(?<=state )\w+"
This also prints UP.
Or, if you have Perl installed:
ip link show eth0 | head -n 1 | perl -ne 'print $1 if /eth0.*?state (\w+)/'
In this case, I used the parentheses to form a catch group around what I want: the \w+ right after "state". Thus, this group will be available in the special variable $1 (since it is the first capture group). This code also prints UP, but without the line break at the end. If you want the line break, just exchange for:
ip link show eth0 | head -n 1 | perl -ne 'print "$1\n" if /eth0.*?state (\w+)/'
But I still find the solution with awk simpler.
No, it doesn’t need to be regex. I just tested this code, returned UP as said, but what is "awk"?
– Matheus Leite
@Matheusleite I updated the answer with an explanation
– hkotsubo
I understand perfectly, thank you!
– Matheus Leite