ifconfig에서 인터페이스 이름, hwaddress 및 IP 주소 추출(ip 명령이 아닌 ifconfig를 사용해야 함)

ifconfig에서 인터페이스 이름, hwaddress 및 IP 주소 추출(ip 명령이 아닌 ifconfig를 사용해야 함)

입력 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}'), 각 줄에서 모든 일치 패턴을 사용할 수는 없기 때문에 원하는 출력을 얻을 수 없습니다.

따라서 인터페이스에 대한 입력 2 파일에 일치하는 패턴 빈 "inet addr:"을 추가하려고 생각하는 것은 본딩의 일부이므로 괜찮을 것입니다.

  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

참고: 요청한 출력에는 bond0:0의 IP 주소로 192.168.0.2가 있었지만 샘플 데이터에는 인터페이스와 마찬가지로 192.168.0.1이 있었습니다 bond0.

스크립트에서 "선택적" 줄의 주석 처리를 제거하면 IP 주소 또는 MAC 주소 필드가 비어 있어도 탭으로 구분된 출력 필드가 항상 3개가 있게 됩니다.

출력은 다음과 같습니다:

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

관련 정보