Sad awk grep help needed

Given a line like
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP group default qlen 1000
or
2: enp5s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000

How do I extract the interface name or more precisely all the non-space characters following “2:” up to the next “:” and then stop so I dont bring in the MAC address on the next line?

Asking for a friend who has never got his head around sed, awk and friends…
I could do

ip a >/tmp/ipa.txt
grep "2: " /tmp/ipa.txt|cut -f2 -d':'|cut -c2-

but this seems very kludgey

however it does seem to produce the output I need.

1 Like
❯ echo "2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP group default qlen 1000" | awk -F ":" '{ print $2 }' | xargs
eth0
❯ echo "2: enp5s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000" | awk -F ":" '{ print $2 }' | xargs
enp5s0

Is that what you want?

1 Like

Yep but I only want the interface name so I can do …


ip a > /tmp/ipa.txt
ACTIVE_IF=`grep "2: " /tmp/ipa.txt|cut -f2 -d':'|cut -c2-`
echo $ACTIVE_IF
#clean up
rm /tmp/ipa/txt

LOCAL_IP=$(echo `ifdata -pa $ACTIVE_IF`)

Btw, you don’t need that intermediate text file. You can pipe the output of ip a straight into grep.

Also, the $(...) notation is preferable to backticks now. I can’t remember exactly where I read that, but pretty sure I did. Plus, imo it’s just nicer to read.

3 Likes

Yes that works - thank you :grinning:

willie@gagarin:~$ ACTIVE_IF=$(ip a |grep "2: " | awk -F ":" '{ print $2 }' | xargs) && echo $ACTIVE_IF
enp5s0

and on AWS

ubuntu@ip-172-31-7-155:~/comnet-install$ ACTIVE_IF=$(ip a |grep "2: " | awk -F ":" '{ print $2 }' | xargs) && echo $ACTIVE_IF
eth0
1 Like

Happy awk grep now?

1 Like

yes that works fine and is much cleaner.
Im working on choice of testnet/comnet to connect to next.

GitHub - safenetwork-community/comnet-install: script to set up comnet - community testing for the SAFE network PRs welcome

The initial Y/n needs sorted as well

2 Likes

Sed, awk, xargs etc all look terrifying. I watched a video which took away a lot of the scary voodoo (but of course I forgot it straight away). There will always be a market for the likes of @chriso who have ventured into the heart of darkness and emerged with the secret

3 Likes

@davidpbrown is another who knows this stuff inside out. I once thought I understood simple regexes but unless you are using them regularly, its not the kind of knowledge I can retain too well.

1 Like

Yeah DPB is another master of the dark arts.

1 Like
ip link show | sed -n '/^[0-9]/{s/^[0-9]*: \(.*\):.*$/\1/;p}'

or, if you only want interface 2 for some reason

ip link show | sed -n '/^2:/{s/^[0-9]*: \(.*\):.*$/\1/;p}'

or you can use a different output format that’s easier to parse , like

 ip -oneline link show | sed -e 's/^[^:]*: *//' -e 's/:.*$//'

or

ip -brief link show | awk '{print $1;}'

or, if you want to get all the interface names without having to parse anything, withouth write-only regular expression code, and without forking

(cd /sys/class/net; echo *)

… but the real reason I’m posting an answer is to suggest that about the time you get to the point of parsing stuff like that, it’s a good time to switch to another programming language. Complicated shell scripts are the path of madness. Python isn’t great, but it’s a lot easier to write a working, relatively complicated program in a language like Python than in a shell.

On edit: oops, that does fork. But it doesn’t do an exec…

2 Likes

And if you want to not use grep, awk or sed then use just bash script

while read a b ; do if [[ $a == 2: ]]; then iface="${b%%:*}"; echo $iface; break; fi; done <<< $( ip link )
1 Like

Its a simple script to get n00bs up and running. Im guessing 99% of the time the 2nd interface listed is the active network.

thats neat, I think I can do away with moreutils if I do EDIT No, moreutils is needed for ifdata at line 41

willie@gagarin:~$ (cd /sys/class/net; echo *)|awk '{print $1;}'
enp5s0

but as you say by the time we need to get more network info, its time for Python or even Rust.

Next I want to make the node connection info configurable so its easy to switch between @Josh @folaht and the official testnets. With configureable vault sizes, I think thats all we need for now. This is just to get a few more lurkers comfortable enough to join in.

Then create a similar script for Windows, Mac and non-Debian distros to get more folk involved

3 Likes

For sure, this is the main purpose. I may be a semi-n00b, but it’s also for people like me who don’t like copying or typing long command strings, just because it’s easy to make silly mistakes that way.

If we all do exactly the same thing, I also think the tests may turn out to be more informative, as well as require less hand-holding.

(Now I really need to go to bed.)

3 Likes

You could use ip route to get the device that routes internet traffic:

ip route get 1.1.1.1 | sed -nEe 's/.* dev (\w+) .*/\1/p'

(The sed part takes whatever word is after dev.)

This is what an online question will do, it will give you plenty of answers that you didn’t ask for… :wink:

7 Likes

Everything being discussed here is well within the bounds of using shell. Nothing too complex going on.

Python is awesome!

4 Likes

Tips for those bashing heads with bash:

3 Likes

This topic was automatically closed after 59 days. New replies are no longer allowed.