4

我需要将命令的结果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

我知道我应该用 thesed或类似的东西来做。现在我有以下“脚本”:

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

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

4

4 回答 4

6

请注意,ifconfig输出因平台而异,因此这不是一种非常便携的方式。

至于 sed 解决方案,我认为您需要将解析分成多个步骤,这样的事情应该可以工作(GNU sed):

解析.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
于 2013-02-07T00:38:44.743 回答
2

我已经接受了雷神的回答,但这是我的解决方案,有点不同。我在等待答案的时候考虑了一下。

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

主要优点 - 它可以按原样调用。第二个优点是接口的顺序与接口索引一致(我在开始比较ifconfigand的结果时得到了这个ip addr)。

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

于 2013-02-07T01:12:26.700 回答
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

如您所见,它们的顺序不同,但我无法得到它。

于 2013-02-07T00:35:19.043 回答
0

为了更好的可读性和可维护性,您可以为此使用 awk。这是使用 GNU 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", $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
于 2013-02-07T01:30:32.400 回答