通过单个命令(管道)打印接口 IP 地址

通过单个命令(管道)打印接口 IP 地址

如果配置给出以下输出:

   eth0      Link encap:Ethernet  HWaddr 4c:87:0e:z3:e7:11  
              UP BROADCAST MULTICAST  MTU:1500  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:35767 errors:0 dropped:0 overruns:0 frame:0
          TX packets:35767 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:5053027 (5.0 MB)  TX bytes:5053027 (5.0 MB)

vmnet1    Link encap:Ethernet  HWaddr 60:80:66:m0:00:01  
          inet addr:192.168.139.1  Bcast:192.168.139.255  Mask:255.255.255.0
          inet6 addr: fe80::250:56ff:fec0:1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:70 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

我目前需要像这样的输出

eth0   
wlan0   127.0.0.1
vmnet1  192.168.139.1

所以我运行命令

ifconfig | awk '/encap|inet addr/{  print }'

但我现在陷入困境,因为我需要根据天气合并 2 行,下一行包含 ipaddress 模式。虽然 shell 脚本可能可以解决问题,但我需要一个简单的单命令解决方案。虽然 awk 中有 for 循环,但是向前查看下一行、匹配然后在控制台上打印对我来说是一个挑战。

或者是否有一个简单的命令/标志来实现这样的目的?

Route 命令似乎可以解决问题(awk 字段提取!!),但它没有列出非活动接口。

答案1

如果您运行的是 GNU/Linux:

for DEV in /sys/class/net/*; do
    printf "%-10s %s\n" ${DEV##*/} $(ip addr show ${DEV##*/} | \
      sed -rne '/inet/s:\s+inet\s+([0-9.]+).*:\1:gp');
done

或者如果ifconfig是一个要求:

for DEV in /sys/class/net/*; do
    printf "%-10s %s\n" ${DEV##*/} $(ifconfig ${DEV##*/} | \
      sed -rne '/inet adr/s/\s+inet adr:([0-9.]+).*/\1/gp');
done

它产生

eth0       192.168.10.34
eth1       
lo         127.0.0.1
...

虽然需要iproute2

答案2

终于找到了基于ifconfig的解决方案!

String s="ifconfig | awk -F '[ :]' '/encap|inet addr/{ if($1 != \"\" ){ print $1 \":\" $13 } else print $13 }'| awk -F \":\" '{print $1}'| awk '{  curr=$1 ; if(!system(\"echo \"$1\"|grep ^[0-9]>/dev/null\")) {print prev \"\\t : \" curr;prev=\"\"} else { if(prev!=\"\") {print prev \"\\t : not assigned\" }; prev=$1 }   }'"

解释 :

root$ ifconfig | awk -F '[ :]' '/encap|inet addr/{ if($1 != "" ){ print $1 ":" $13 } else print $13 }'| awk -F ":" '{print $1}'
eth0
lo
127.0.0.1
vmnet1
192.168.139.1
vmnet8
192.168.152.1
wlan0
10.208.7.86

所以,我已将上述输出通过管道传输到另一个 awk 命令:

| awk '{  curr=$1 ; if(!system("echo "$1"|grep ^[0-9]>/dev/null")) {print prev "\t : " curr;prev=""} else { if(prev!="") {print prev "\t : not assigned" }; prev=$1 }   }'

在这里,如果我找到两个连续的接口名称,那么我打印的名称上一页带自定义消息的 ious 接口“未分配“ .如果我在字符串中得到数字模式,则当前字符串(ip地址)以及上一页打印了 io 接口名称!

答案3

ifconfig-a| awk '/Link/ {n=$1} /addr/ {print n, substr($2,index($2,":")+1))}'

简单地说,获取姓名,然后当出现地址时,打印冒号后面的姓名和地址。

答案4

另一种可能性是ifconfigawk。也应该适用于别名接口 (eth0:1) 和 vlan 接口 (eth0.1):

ifconfig | awk 'BEGIN {RS="\n\n"; } { if ($7 != "addr:") {print $1,$7} }'

RSawk 中的参数是记录分隔符,我们将其设置为 2 个换行符。它导致 awk 将有关每个接口的所有信息合并到一行中。我还禁止未配置任何 IPv4 地址的打印接口。

我使用此命令显示每个接口的 IP 及其解析的主机名:

ifconfig | awk 'BEGIN {RS="\n\n"; } { if ($7 != "addr:") {print $1,$7} }' | sed 's/addr://g' | while read iface ip; do
  echo $iface $ip $(getent hosts | awk '/^'$ip'/ {print $2}');
done

输出看起来像:

bond0 10.126.226.102 deh137.abc.biz.
bond0:1 10.126.227.10 aeudi64.abc.biz.
bond0:7 10.126.226.141 rtlci22.abc.biz.
bond1.625 10.126.216.142
bond1.654 10.126.228.102 deh137s.abc.biz.

编辑:更新了最后一个命令,使其可以与 DNS 和基于 /etc/hosts 的解析一起使用。

相关内容