입력 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:"을 추가하려고 생각하는 것은 본딩의 일부이므로 괜찮을 것입니다.
인터페이스 줄 뒤에 빈 "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
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