2013-02-06 19 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