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

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 アドレスがインターフェース名とタイプの 2 行目に存在することです。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

2 つ目の問題ifconfig -aは、出力に IP アドレスがない場合にゼロアドレスを挿入する方法がわからないことです。

4

4 に答える 4

6

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
于 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

主な利点 - そのまま呼び出すことができます。2 番目の利点は、インターフェイスの順序付けがインターフェイス インデックスと一致することです (これは、 と の結果を比較し始めたときにわかりましたifconfig) 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'[: ]'複数の区切り文字を定義します: :and (スペース)。
  • {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 の 1 つの方法を次に示します。

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
于 2013-02-07T01:30:32.400 に答える