如何在awk中修改来自ifconfig的输入
How to modify input from ifconfig in awk
编辑:
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
我有其他有用的用户编写的这个很好的代码,我需要修改它的输出。
我必须承认我很难做到。
ifconfig |
awk '
/^[[:alnum:]]+: / {
n =
p = 1
}
n !~ /^lo/ && /^[[:blank:]]+(inet|ether) / {
if (p) {
print n
p = 0
}
print ,
}'
这是它的正确输出:
enp2s0f1:
ether xx:xx:xx:xx:xx:xx
wlp3s0:
inet xxx.xxx.xxx.xxx
ether xx:xx:xx:xx:xx:xx
这就是我需要修改它的方式:
(已创建列 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
你可以试试这个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 ( !~ /^lo/) inet=} inet && /^[[:blank:]]+inet / {ip= " " } inet && /^[[:blank:]]+ether / {mac= " " } 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
为了使其更具可读性:
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 ( !~ /^lo/) # if not starting with "lo"
inet = # save inet name in var inet
}
inet && /^[[:blank:]]+inet / { # if inet is set and we have inet after spaces
ip = " " # save " " in ip variable
}
inet && /^[[:blank:]]+ether / {# if inet is set and we have ether after spaces
mac = " " # save " " in mac variable
}
END {
if (inet) # if inet is not blank
print inet, ip, mac # print full record
}
' | column -t -s $'\t'
column
命令已用于表格输出。
您可以使用 ip
工具及其 -j
或 -json
选项输出 JSON 格式的答案,可以使用 jq
之类的工具或任何带有 JSON 解析器的编程语言可靠地解析。
这是单行的:
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 )'
或评论独立jq
脚本:
#!/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
)
示例输出:
name ip_address mac_address
lo 127.0.0.1 00:00:00:00:00:00
enp4s0 192.168.1.10 00:24:1d:00:00:00
virbr0 192.168.122.1 52:54:00:00:00:00
编辑: 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
我有其他有用的用户编写的这个很好的代码,我需要修改它的输出。 我必须承认我很难做到。
ifconfig |
awk '
/^[[:alnum:]]+: / {
n =
p = 1
}
n !~ /^lo/ && /^[[:blank:]]+(inet|ether) / {
if (p) {
print n
p = 0
}
print ,
}'
这是它的正确输出:
enp2s0f1:
ether xx:xx:xx:xx:xx:xx
wlp3s0:
inet xxx.xxx.xxx.xxx
ether xx:xx:xx:xx:xx:xx
这就是我需要修改它的方式:
(已创建列 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
你可以试试这个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 ( !~ /^lo/) inet=} inet && /^[[:blank:]]+inet / {ip= " " } inet && /^[[:blank:]]+ether / {mac= " " } 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
为了使其更具可读性:
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 ( !~ /^lo/) # if not starting with "lo"
inet = # save inet name in var inet
}
inet && /^[[:blank:]]+inet / { # if inet is set and we have inet after spaces
ip = " " # save " " in ip variable
}
inet && /^[[:blank:]]+ether / {# if inet is set and we have ether after spaces
mac = " " # save " " in mac variable
}
END {
if (inet) # if inet is not blank
print inet, ip, mac # print full record
}
' | column -t -s $'\t'
column
命令已用于表格输出。
您可以使用 ip
工具及其 -j
或 -json
选项输出 JSON 格式的答案,可以使用 jq
之类的工具或任何带有 JSON 解析器的编程语言可靠地解析。
这是单行的:
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 )'
或评论独立jq
脚本:
#!/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
)
示例输出:
name ip_address mac_address
lo 127.0.0.1 00:00:00:00:00:00
enp4s0 192.168.1.10 00:24:1d:00:00:00
virbr0 192.168.122.1 52:54:00:00:00:00