shellawkifconfig

How to modify input from ifconfig in awk


Edit: Sample output of ifconfig

enp2s0f1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether xx:xx:xx:xx:xx:xx  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 2540  bytes 207824 (202.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2540  bytes 207824 (202.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet xxx.xxx.xxx.xxx  netmask xxx.xxx.xxx.x  broadcast xxx.xxx.xxx.xxx
        inet6 xxxx::xxxx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x20<link>
        ether xx:xx:xx:xx:xx:xx  txqueuelen 1000  (Ethernet)
        RX packets 1413004  bytes 634560717 (605.1 MiB)
        RX errors 0  dropped 2  overruns 0  frame 0
        TX packets 279420  bytes 36406046 (34.7 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

I have this nice written code by other helpful user and I need to modify output of it. I must admit I have a hard time doing it.

ifconfig |
awk '
/^[[:alnum:]]+: / {
   n = $1
   p = 1
}
n !~ /^lo/ && /^[[:blank:]]+(inet|ether) / {
   if (p) {
      print n
      p = 0
   }
   print $1, $2
}'

Here's correct output from it:

enp2s0f1:
ether xx:xx:xx:xx:xx:xx
wlp3s0:
inet xxx.xxx.xxx.xxx
ether xx:xx:xx:xx:xx:xx

And this is how I need it to be modifed:

(with created columns inet_name, ip_address, mac_address)

inet_name ip_address           mac_address
enp2s0f1:                      ether xx:xx:xx:xx:xx:xx
wlp3s0:   inet xxx.xxx.xxx.xxx ether xx:xx:xx:xx:xx:xx

Solution

  • You may try this awk:

    ifconfig |
    awk -v OFS='\t' 'BEGIN {ip=mac=" "; print "inet_name", "ip_ddress", "mac_address"} /^[[:alnum:]]+: / {if (inet) {print inet, ip, mac; ip=mac=" "; inet=""} if ($1 !~ /^lo/) inet=$1} inet && /^[[:blank:]]+inet / {ip=$1 " " $2} inet && /^[[:blank:]]+ether / {mac=$1 " " $2} END {if (inet) print inet, ip, mac}' | column -t -s $'\t'
    
    inet_name  ip_ddress             mac_address
    enp2s0f1:                        ether xx:xx:xx:xx:xx:xx
    wlp3s0:    inet xxx.xxx.xxx.xxx  ether xx:xx:xx:xx:xx:xx
    

    To make it more readable:

    ifconfig |
    awk -v OFS='\t' '
    # set output field separator to tab
    BEGIN {
       # initialize ip and mac variables
       ip = mac = " "
       print header record
       print "inet_name", "ip_ddress", "mac_address"
    }
    /^[[:alnum:]]+: / {            # if no blank at start
       if (inet) {                 # print full record if not first time
          print inet, ip, mac
          ip = mac = " "           # reset variables
          inet = ""
       }
       if ($1 !~ /^lo/)            # if not starting with "lo"
          inet = $1                # save inet name in var inet
    }
    inet && /^[[:blank:]]+inet / { # if inet is set and we have inet after spaces
       ip = $1 " " $2              # save $1 " " $2 in ip variable
    }
    inet && /^[[:blank:]]+ether / {#  if inet is set and we have ether after spaces
       mac = $1 " " $2             # save $1 " " $2 in mac variable
    
    }
    END {
       if (inet)                   # if inet is not blank
          print inet, ip, mac      # print full record
    }
    ' | column -t -s $'\t'