Извлечь имя интерфейса, hwaddress и IP-адрес из ifconfig (необходимо использовать команды ifconfig, а не ip)

Извлечь имя интерфейса, hwaddress и IP-адрес из ifconfig (необходимо использовать команды ifconfig, а не ip)

Вход 1

eno16780032: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 192.168.0.1 netmask 255.255.255.255  broadcast 192.168.0.254
    ether 00:50:56:00:00:00  txqueuelen 1000  (Ethernet)
eno33559296: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 192.168.0.2  netmask 255.255.255.255  broadcast 192.168.0.254
    ether 00:50:56:00:00:01  txqueuelen 1000  (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
    inet 127.0.0.1  netmask 255.0.0.0
    loop  txqueuelen 0  (Local Loopback)

Вход 2

bond0   Link encap:Ethernet  HWaddr 00:50:56:00:00:00
        inet addr:192.168.0.1   Bcast:192.168.0.254  Mask:255.255.254.255
        UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
bond0:0 Link encap:Ethernet  HWaddr 00:50:56:00:00:00
        inet addr:192.168.0.1  Bcast:192.168.0.254  Mask:255.255.254.255
        UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
eth0    Link encap:Ethernet  HWaddr 00:50:56:00:00:00
        UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
eth1    Link encap:Ethernet  HWaddr 00:50:56:00:00:00
        UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
lo      Link encap:Local Loopback
        inet addr:127.0.0.1  Mask:255.0.0.0
        UP LOOPBACK RUNNING  MTU:65536  Metric:1

Я хочу, чтобы вывод был таким, (в основном, чтобы извлечьИнтерфейс, IP и аппаратный адрес)

Вывод1

eno16780032 192.168.0.1 00:50:56:00:00:00 
eno33559296 192.168.0.2 00:50:56:00:00:01   
lo          127.0.0.1

Вывод2

bond0   192.168.0.1 00:50:56:00:00:00
bond0:0 192.168.0.2 00:50:56:00:00:00
eth0                00:50:56:00:00:00 ===> No IP since its under bonding
eth1                00:50:56:00:00:00 ===> No IP since its under bonding
lo      127.0.0.1

Я пробовал использовать awk (awk '/flags|Link/{a=$1;hw=$NF;next;} /inet /{ip=$2;print a,ip,hw}'), , но так как не все шаблоны соответствия доступны в каждой строке, не удалось получить желаемый вывод.

Поэтому думаю добавить пустой шаблон соответствия "inet addr:" в файл ввода 2 для интерфейсов, являющихся частью связывания, и все будет хорошо.

  1. Можете ли вы помочь добавить пустой «inet addr:» после строки интерфейса?

     eth0    Link encap:Ethernet  HWaddr 00:50:56:00:00:00
             UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
             inet addr:   <==== Insert empty line
    

или

  1. Чтобы получить желаемый результат, как указано выше.

решение1

awk 'BEGIN { OFS="\t" }; # use tab for output separator

     ! /^ / {   # line doesnt begin with a space, must be an interface line, extract it
       i=gensub(/:$/,"",1,$1)
       mac[i]=$5;     # this will either be a HWAddr or empty
       ifaces[i]=1
     };

     /^ +inet/ { ip[i] = ip[i] " " gensub(/addr:/,"",1,$2) };

     /^ +ether/ { mac[i]=$2};  # this will only match if there WASNT a HWAddr on the iface line

     END {
       for (i in ifaces) {
         sub(/^ +/,"",ip[i]); # remove unwanted space from beginning of ip addresses
         #if (ip[i]  == "") ip[i]  = "--"; #optional
         #if (mac[i] == "") mac[i] = "--"; #optional
         print i, ip[i], mac[i]
       }
     }' filename | sort

(или просто передайте ifconfigему ссылку, а не дайте ему имя входного файла)

Этот скрипт awk может обрабатывать любой вариант ifconfigвывода и выводит три поля, разделенных табуляцией: имена интерфейсов, IP-адреса и MAC-адреса.

Если во втором поле указано несколько IP-адресов, они разделяются пробелом.

Вывод при запуске на input1 и передаче в sort:

eno16780032     192.168.0.1     00:50:56:00:00:00
eno33559296     192.168.0.2     00:50:56:00:00:01
lo      127.0.0.1

Вывод при запуске на input2 и передаче в sort:

bond0:0 192.168.0.1     00:50:56:00:00:00
bond0   192.168.0.1     00:50:56:00:00:00
eth0            00:50:56:00:00:00
eth1            00:50:56:00:00:00
lo      127.0.0.1

ПРИМЕЧАНИЕ: в запрошенном вами выводе в качестве IP-адреса для bond0:0 указан 192.168.0.2, но в ваших данных образца указан 192.168.0.1, как и для интерфейса bond0.

Если вы раскомментируете «необязательные» строки в скрипте, это гарантирует, что всегда будут три выходных поля, разделенных табуляцией, даже если поле IP-адреса или MAC-адреса пустое.

Вывод будет выглядеть так:

eno16780032     192.168.0.1     00:50:56:00:00:00
eno33559296     192.168.0.2     00:50:56:00:00:01
lo      127.0.0.1       --

и

bond0:0 192.168.0.1     00:50:56:00:00:00
bond0   192.168.0.1     00:50:56:00:00:00
eth0    --      00:50:56:00:00:00
eth1    --      00:50:56:00:00:00
lo      127.0.0.1       --

Дополнительные комментарии:

Этоошибкаигнорировать ipкоманду. Это стандарт в Linux уже много лет, и многие программы, которые добавляют вторичные/альтернативные/"псевдонимы" IP-адреса к интерфейсу, будут использовать его. Вторичные IP-адреса, добавленные к интерфейсу таким образом, будутТОЛЬКОбудут отображаться с помощью ip addr show, они НЕ будут отображаться при ifconfigзапуске.

ifconfigследует рассматривать только как устаревшую версию, по крайней мере, в Linux.

решение2

Наивное, но эффективное решение — читать вывод ifconfigв обратном порядке; таким образом, каждый раз, когда мы сталкиваемся с первой строкой блока, мы либо находим интересующие нас поля, либо можем с уверенностью предположить, что они отсутствуют. Учитывая скрипт AWK:

{
  for (i = 1; i  <= NF; i++) {
    if ($i == "inet") {
      ip = $(i+1)
      sub(/.*:/, "", ip)
    }
    if ($i == "HWaddr" || $i == "ether")
      hw = $(i+1)
  }
}
/^[^[:blank:]]/ {
  nm = $1
  sub(/:$/, "", nm)
  print nm,ip,hw
  nm = ""
  ip = ""
  hw = ""
}

и если вы сохранили его как awkscript, то вы можете сделать следующее:

ifconfig | tac | awk -f awkscript | tac | column -s ' ' -t

Если нестандартная tacкоманда вам недоступна, этот скрипт AWK можно легко модифицировать, чтобы сохранить весь входной поток в массиве и обработать его в обратном порядке в блоке END.

решение3

$ cat tst.awk
!/^[[:space:]]/ { if (NR>1) prt() }
{ rec = rec FS $0 }
END { prt() }

function prt(   flds,i,nf,map) {
    sub(/: /," ",rec)
    sub(/ ether /," HWaddr ",rec)
    sub(/ inet addr:/," inet ",rec)

    nf = split(rec,flds)
    map["iface"] = flds[1]
    for (i=2; i<nf; i++) {
        map[flds[i]] = flds[i+1]
    }
    print map["iface"], map["inet"], map["HWaddr"]

    rec = ""
}

$ awk -f tst.awk file1 | column -s' ' -t
eno16780032  192.168.0.1  00:50:56:00:00:00
eno33559296  192.168.0.2  00:50:56:00:00:01
lo           127.0.0.1

$ awk -f tst.awk file2 | column -s' ' -t
bond0    192.168.0.1  00:50:56:00:00:00
bond0:0  192.168.0.1  00:50:56:00:00:00
eth0                  00:50:56:00:00:00
eth1                  00:50:56:00:00:00
lo       127.0.0.1

Связанный контент