bash 如何格式化ifconfig的输出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14739483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to format output of ifconfig
提问by Anton Boritskiy
I need to transfom the result of command ifconfig -ato the following format
我需要将命令的结果ifconfig -a转换为以下格式
IFACE eth0 192.168.30.8 Ethernet
IFACE eth1 212.233.112.171 Ethernet
IFACE lo 127.0.0.1 Local Loopback
IFACE pan0 0.0.0.0 Ethernet
IFACE tunl0 0.0.0.0 IPIP Tunnel
I know that I should do that with the sedor something similar.
For now I have the following "script":
我知道我应该用sed或类似的东西来做这件事。现在我有以下“脚本”:
ifconfig -a | sed -r -n -e 'N' -e 's/(\w+)(\s*)(Link\sencap:)(\w+(\s\w+)*)([^\n]*)\n\s+(inet\saddr:)([0-9]{1,3}(\.[0-9]{1,3}){3}).*/IFACE /p'
The original ifconfig -aoutput is (...means ommited parts)
原始ifconfig -a输出是(...表示省略部分)
eth0 Link encap:Ethernet HWaddr f4:ce:46:99:22:57
inet addr:192.168.30.8 Bcast:192.168.31.255 Mask:255.255.254.0
...
eth1 Link encap:Ethernet HWaddr 00:23:7d:fd:a2:d0
inet addr:212.233.112.171 Bcast:212.233.112.175 Mask:255.255.255.240
...
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
...
pan0 Link encap:Ethernet HWaddr f6:d0:8a:0e:7b:95
BROADCAST MULTICAST MTU:1500 Metric:1
...
tunl0 Link encap:IPIP Tunnel HWaddr
NOARP MTU:1480 Metric:1
...
The first problemwith this transformation is that IP address resides on the second line from the interface name and type. A used the -Nargument to concat the lines, but they are being concat in pairs, and if the name of the interface is on odd line - I have troubles: script skips the interface on the odd line, like this (NOTE that there are no mentioning about pan0 in the output.):
此转换的第一个问题是 IP 地址位于接口名称和类型的第二行。A 使用-N参数连接行,但它们成对连接,如果接口的名称在奇数行 - 我有麻烦:脚本跳过奇数行的接口,像这样(注意没有在输出中提到 pan0。):
IFACE eth0 192.168.30.8 Ethernet
IFACE eth1 212.233.112.171 Ethernet
IFACE lo 127.0.0.1 Local Loopback
IFACE tunl0 IPIP Tunnel
The second problemis that I don't know how to insert zero-address when there are no IP adress in ifconfig -aoutput.
第二个问题是,当ifconfig -a输出中没有IP地址时,我不知道如何插入零地址。
回答by Thor
Note that ifconfigoutput varies with platforms, so this is not a very portable way of doing it.
请注意,ifconfig输出因平台而异,因此这不是一种非常便携的方法。
As to a sed solution, I think you need to break the parsing into multiple steps, something like this should work (GNU sed):
至于 sed 解决方案,我认为您需要将解析分解为多个步骤,这样的事情应该可以工作(GNU sed):
parse.sed
解析.sed
s/^([^ ]+) */\n/ # interface name
s/Link encap:(.*)( |$).*// # link encapsulation
N # append next line to PS
/inet addr/! s/\n[^\n]*$/\n0.0.0.0\n/ # use 0.0.0.0 if no "inet addr"
s/ *inet addr:([^ ]+).*/\n/ # capture ip address if present
s/\n[^\n]*$// # cleanup the last line
s/([^\n]+)\n([^\n]+)\n([^\n]+)/IFACE /p # print entry
s/.*// # empty PS
: loop # \
N # \
/^\n$/b # skip until next empty line
s/.*// # /
b loop # /
Explanation
解释
The idea is to capture all the relevant information in pattern space with newline delimiters.
这个想法是用换行符捕获模式空间中的所有相关信息。
Testing
测试
Run like this:
像这样运行:
ifconfig -a | sed -rf parse.sed
Output:
输出:
IFACE eth0 192.168.30.8 Ethernet
IFACE eth1 212.233.112.171 Ethernet
IFACE lo 127.0.0.1 Local Loopback
IFACE pan0 0.0.0.0 Ethernet
IFACE tunl0 IPIP Tunnel
回答by Anton Boritskiy
I've already accepted the Thor's answer, but here is my solution, which is a bit different. I was thinking it over while waiting for an answer.
我已经接受了雷神的回答,但这是我的解决方案,它有点不同。在等待答案的时候,我在思考。
ip addr | sed -r ':a;N;$!ba;s/\n\s/ /g' | sed -r -n -e 's/^([0-9]+):\s(\w+).*(link\/(\w+))\s[a-f0-9:.]{,17}\sbrd\s[a-f0-9:.]{,17}\s*(inet\s([0-9]{1,3}(\.[0-9]{1,3}){3})).*/IFACE /p' -e 's/^([0-9]+):\s(\w+).*(link\/(\w+))\s[a-f0-9:.]{,17}\sbrd\s[a-f0-9:.]{,17}.*/IFACE 0.0.0.0 /p'
output:
输出:
IFACE lo 127.0.0.1 loopback
IFACE eth0 192.168.30.8 ether
IFACE eth1 212.233.112.171 ether
IFACE pan0 0.0.0.0 ether
IFACE tunl0 0.0.0.0 ipip
the main advantage - it can be called as is. The second advantage is that the ordering of interfaces coinsides with interface indexes (I got this when started comparing results of ifconfigand ip addr).
主要优点 - 它可以被称为原样。第二个优点是接口的排序与接口索引同时存在(我在开始比较ifconfigand 的结果时得到了这个ip addr)。
But Thorn's solution is much more readable and maintainable.
但是 Thorn 的解决方案更具可读性和可维护性。
回答by fedorqui 'SO stop harming'
I got something!
我有东西!
ifconfig -a | tr -s ' ' | awk -F'[: ]' '
{if (/^[a-z]/) printf "IFACE " " " }
{if (/inet addr:/) print " " }'
Explanation:
解释:
tr -s ' 'delete multiple spaces.-F'[: ]'defines multiple delimiters::and(space).{if (/^[a-z]/) ...whenever somethings begins with a letter, print field 1 and 4.{if (/inet addr:/) ...whenever somethings contains_inet addr_, print field $4
tr -s ' '删除多个空格。-F'[: ]'定义多个分隔符::和(空格)。{if (/^[a-z]/) ...每当某事以字母开头时,打印字段 1 和 4。{if (/inet addr:/) ...每当有东西包含时_inet addr_,打印字段 $4
Output:
输出:
IFACE lo Local127.0.0.1
IFACE wlan0 Ethernet192.168.1.61
As you can see, they are not in the same order but I could not get it.
如您所见,它们的顺序不同,但我无法理解。
回答by Thor
For better readability and maintainability, you could use awk for this. Here's one way with GNU awk:
为了更好的可读性和可维护性,您可以为此使用 awk。这是 GNU awk 的一种方式:
parse.awk
解析.awk
function get2(s) {
split(s, a, ":")
return a[2]
}
{
link = ip = ""
for(i=2; i<=NF; i++) {
switch($i) {
case /Link encap/ : link = get2($i); break
case /inet addr/ : ip = get2($i); break
}
}
print "IFACE", , (ip=="")?"0.0.0.0":ip, link
}
Run it like this:
像这样运行它:
ifconfig -a | awk -f parse.awk RS='\n\n' FS=' {2,}|\n'
Output:
输出:
IFACE eth0 192.168.30.8 Ethernet
IFACE eth1 212.233.112.171 Ethernet
IFACE lo 127.0.0.1 Local Loopback
IFACE pan0 0.0.0.0 Ethernet
IFACE tunl0 0.0.0.0 IPIP Tunnel

