2013-02-06 22 views
4

的输出格式,我需要命令ifconfig -a的结果transfom以下格式如何使用ifconfig

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 

我知道我应该做的是类似的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 \1 \8 \4/p' 

原来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 
      ... 

这种转变的第一个问题是,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 

第二个问题是,我不知道如何插入零地址当有ifconfig -a输出没有IP地址。

+1

我想你应该与开始而不是'ip addr'的输出。然后你需要用类似的方式解析它。 – Keith

+0

'ip addr'输出有同样的问题 - 'ip address'在设备名后面的下一行( –

+0

)关于第一个问题,可以使用'awk'FNR == number_of_line {print}''选择行号。 – fedorqui

回答

4

请注意,ifconfig输出随平台而异,所以这不是一个非常便携的方式。

对于一个SED解决方案,我认为你需要打破解析成多个步骤,这样的事情应该工作(GNU SED):

parse.sed

s/^([^ ]+) */\1\n/        # interface name 
s/Link encap:(.*)( |$).*/\1/     # 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:([^ ]+).*/\1\n/     # capture ip address if present 
s/\n[^\n]*$//         # cleanup the last line 
s/([^\n]+)\n([^\n]+)\n([^\n]+)/IFACE \1 \3 \2/p # print entry 
s/.*//           # empty PS 
: loop           # \ 
N            # \ 
/^\n$/b           # skip until next empty line 
s/.*//           #/
b loop           #/

说明

这个想法是使用换行符分隔符捕获模式空间中的所有相关信息。

测试

像这样运行:

ifconfig -a | sed -rf parse.sed 

输出:

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 
+0

WOW!有一个问题,0.0.0.0被检测词“BROADCAST MULTICAST”取代,对吗?如果没有明确设置“inet addr:”,是否可以改变这种行为以插入0.0.0.0? –

+0

@AntonBoritskiy:简化了一点,看到更新版本 – Thor

+0

太棒了!非常感谢! –

1

我得到了一些东西!

ifconfig -a | tr -s ' ' | awk -F'[: ]' ' 
    {if (/^[a-z]/) printf "IFACE " $1 " " $4} 
    {if (/inet addr:/) print " " $4}' 

说明:

  • tr -s ' '删除多个空格。
  • -F'[: ]'定义了多个分隔符::(空格)。
  • {if (/^[a-z]/) ...每当出头开头的信,打印场1和4
  • {if (/inet addr:/) ...每当出头包含_inet addr_,印刷领域$ 4

输出:

IFACE lo Local127.0.0.1 
IFACE wlan0 Ethernet192.168.1.61 

正如你所看到的,他们不是相同的顺序,但我无法得到它。

0

我已经接受了托尔的答案,但这里是我的解决方案,这是一个有点不同。我在等待答案时正在考虑它。

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 \2 \6 \4/p' -e 's/^([0-9]+):\s(\w+).*(link\/(\w+))\s[a-f0-9:.]{,17}\sbrd\s[a-f0-9:.]{,17}.*/IFACE \2 0.0.0.0 \4/p' 

输出:

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 

主要优势 - 它可以被称为是。第二个好处是接口排序与界面索引(我开始比较ifconfigip addr的结果)。

但索恩的解决方案是更具可读性和可维护性。

0

为了更好的可读性和可维护性,你可以使用AWK这一点。下面是与GNU awk的一个办法:

parse.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", $1, (ip=="")?"0.0.0.0":ip, link 
} 

运行这样的:

ifconfig -a | awk -f parse.awk RS='\n\n' FS=' {2,}|\n' 

输出:

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