How to modify input from ifconfig in awk How to modify input from ifconfig in awk shell shell

How to modify input from ifconfig in awk


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_addressenp2s0f1:                        ether xx:xx:xx:xx:xx:xxwlp3s0:    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 tabBEGIN {   # 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'
  • column comman has been used for tabular output.


Instead of parsing the output of ifconfig which is not a reliable API data exchange, you could use the ip tool instead with its -j or -json option to output JSON formatted answer that can be reliably parsed with a tool like jq or any programming language with a JSON parser.

Here it is as a one-liner:

ip -json addr show |  jq -r '"name\tip_address\tmac_address", ( .[] | if (.addr_info | length) > 0 then .ifname + "\t" + (.addr_info[] | select(.family=="inet")).local + "\t" + .address else empty end )'

Or commented stand-alone jq script:

#!/usr/bin/env -S jq -rf# Print header line"name\tip_address\tmac_address",(  # Stream all results array  .[] |  # If interface has a non-empty addr_info array  if (.addr_info | length) > 0  then    # Print interface name as first column    .ifname + "\t" + (    # Print ipv4 address as second column      .addr_info[] | select(.family=="inet")    ).local + "\t" +    # Print mac address as third column    .address  else  # Do nothing if interface has no ip address    empty  end)

Example output:

name    ip_address      mac_addresslo      127.0.0.1       00:00:00:00:00:00enp4s0  192.168.1.10    00:24:1d:00:00:00virbr0  192.168.122.1   52:54:00:00:00:00