0

ifconfig gives following output:

   eth0      Link encap:Ethernet  HWaddr 4c:87:0e:z3:e7:11  
              UP BROADCAST MULTICAST  MTU:1500  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:35767 errors:0 dropped:0 overruns:0 frame:0
          TX packets:35767 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:5053027 (5.0 MB)  TX bytes:5053027 (5.0 MB)

vmnet1    Link encap:Ethernet  HWaddr 60:80:66:m0:00:01  
          inet addr:192.168.139.1  Bcast:192.168.139.255  Mask:255.255.255.0
          inet6 addr: fe80::250:56ff:fec0:1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:70 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

I presently need output like

eth0   
wlan0   127.0.0.1
vmnet1  192.168.139.1

so i run command

ifconfig | awk '/encap|inet addr/{  print }'

but i am stuck now, as i need to combine 2 lines based on weather the next line contains the ipaddress pattern. Though shell script may do the trick , But i need a simple single command solution. Though for loops are there in awk , but forward looking into next line , matching & then printing on console is challenge for me .

or is there a simple command / flag for achieving such purpose ?

route command seems to do the trick (awk field extraction!!) , but it doesnot list the inactive interfaces.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
puneet336
  • 188
  • 1
  • 7

4 Answers4

3

If you're running GNU/Linux:

for DEV in /sys/class/net/*; do
    printf "%-10s %s\n" ${DEV##*/} $(ip addr show ${DEV##*/} | \
      sed -rne '/inet/s:\s+inet\s+([0-9.]+).*:\1:gp');
done

or if ifconfig is a requirement:

for DEV in /sys/class/net/*; do
    printf "%-10s %s\n" ${DEV##*/} $(ifconfig ${DEV##*/} | \
      sed -rne '/inet adr/s/\s+inet adr:([0-9.]+).*/\1/gp');
done

it yields

eth0       192.168.10.34
eth1       
lo         127.0.0.1
...

Requires iproute2 though.

  • 1
    Also requires Linux! The OP doesn't say what OS this has to work for... although the ifconfig output in the question does look a whole lot like Linux ;) – Celada Feb 09 '15 at 09:29
  • Well, Good spot! I don't know about *BSD but IIRC Mac OSX also includes /sys. Too bad I no longer have a Mac under my hand :D . –  Feb 09 '15 at 09:31
  • first one was okay , but the second one doesn't work properly on debian (simply lists out i'faces without ipaddresses); Though i am expecting a simple command (as i have to execute it using jsch library, so the escape sequences in first solution might prove problemmatic in my case!) – puneet336 Feb 09 '15 at 10:14
  • It is possible with a single sed one-liner but I'm not familiar enough with buffer handling with sed. This said, I doubt a script without escape chars is possible. Strange that the second sample doesn't work though because I tested it on Linux Mint and it worked as expected. –  Feb 09 '15 at 11:32
  • The first doesn't work for interface aliases (like eth0:1), because ip addr show eth0 will show all show also eth0:1, which the script does not expect – Marki555 Jun 07 '16 at 14:31
1

finally found ifconfig based solution!

String s="ifconfig | awk -F '[ :]' '/encap|inet addr/{ if($1 != \"\" ){ print $1 \":\" $13 } else print $13 }'| awk -F \":\" '{print $1}'| awk '{  curr=$1 ; if(!system(\"echo \"$1\"|grep ^[0-9]>/dev/null\")) {print prev \"\\t : \" curr;prev=\"\"} else { if(prev!=\"\") {print prev \"\\t : not assigned\" }; prev=$1 }   }'"

explanation :

root$ ifconfig | awk -F '[ :]' '/encap|inet addr/{ if($1 != "" ){ print $1 ":" $13 } else print $13 }'| awk -F ":" '{print $1}'
eth0
lo
127.0.0.1
vmnet1
192.168.139.1
vmnet8
192.168.152.1
wlan0
10.208.7.86

so , i have piped the above output to another awk command:

| awk '{  curr=$1 ; if(!system("echo "$1"|grep ^[0-9]>/dev/null")) {print prev "\t : " curr;prev=""} else { if(prev!="") {print prev "\t : not assigned" }; prev=$1 }   }'

here , if i find two consecutive interface names, then i print the name of previous interface with custom messge "not assigned" .if i get numeric pattern in string then current string(ipaddress) along with the previous interface name is printed !

0

ifconfig -a | awk '/Link/ {n=$1} /addr/ {print n, substr($2,index($2,":")+1))}'

Simply, grab the name, then when address comes along, print the name and the address, which follows the colon.

Brian
  • 1
0

Another possibility with just ifconfig and awk. Should work also for aliased interfaces (eth0:1) and vlan interfaces (eth0.1):

ifconfig | awk 'BEGIN {RS="\n\n"; } { if ($7 != "addr:") {print $1,$7} }'

RS parameter in awk is record separator and we set it to 2 newlines. It causes awk to merge all info about each interface into single line. I also suppress printing interfaces which don't have any IPv4 address configured.

I use this command to show for each interface its IP and also its resolved hostname:

ifconfig | awk 'BEGIN {RS="\n\n"; } { if ($7 != "addr:") {print $1,$7} }' | sed 's/addr://g' | while read iface ip; do
  echo $iface $ip $(getent hosts | awk '/^'$ip'/ {print $2}');
done

The output looks like:

bond0 10.126.226.102 deh137.abc.biz.
bond0:1 10.126.227.10 aeudi64.abc.biz.
bond0:7 10.126.226.141 rtlci22.abc.biz.
bond1.625 10.126.216.142
bond1.654 10.126.228.102 deh137s.abc.biz.

EDIT: Updated the last command to work both with DNS and with /etc/hosts based resolving.

Marki555
  • 2,098