使用Bash如何在一行中获取网络设备名称和IP地址?

4
我希望能够获取网络接口设备名称(ens###)以及其关联的IP地址(###.###.###.###)。我有获取其中之一的解决方案,但是我找不到可以将每个对(名称+IP)输出到一行的内容。
这是一个获取IP的命令:
ip address | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'

这里我可以获取设备名称

ip address | grep -v lo | cut -d ' ' -f2 | tr ':' '\n' | awk NF

然而,我希望有一种方法可以同时获取两个集合并将它们分别输出到自己的单独行中,类似于此:
ens32 10.0.0.100
ens33 10.1.0.100

编辑:

这里是IP地址的样本输出

[root@centos ~]# ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.100/23 brd 10.0.1.255 scope global dynamic ens32
       valid_lft 83040sec preferred_lft 83040sec
    inet6 0000::000:0000:0000:0000/64 scope link
       valid_lft forever preferred_lft forever
3: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 10.1.0.100/24 brd 10.0.2.255 scope global dynamic ens33
       valid_lft 1277sec preferred_lft 1277sec
    inet6 0000::000:0000:0000:0000/64 scope link
       valid_lft forever preferred_lft forever

解决方案:

这两种方法都可以得到我想要的输出结果。感谢您的帮助!

ip -o addr show scope global | awk '/^[0-9]:/{print $2, $4}' | cut -f1 -d '/'
ip -o addr show scope global | tr -s ' ' | tr '/' ' ' | cut -f 2,4 -d ' '

1
@EdMorton 抱歉,我在这里添加了示例输出 - bc81
2
如果你从 ip -4 addr show scope global 开始,就可以不需要使用 grep -v 来消除 lo 接口。 - Dougie
1
使用 -o 参数,例如 ip -o addr list,将为您提供一个更容易的起点,已经将每个地址放在一行上。 - Charles Duffy
2个回答

4
如果你需要一行命令,可以尝试这个(感谢Dougie提供更精细的ip命令):
ip -oneline -4 addr show scope global | tr -s ' ' | tr '/' ' ' | cut -f 2,4 -d ' '

-oneline参数强制每个接口的输出只有一行。

然后我们从输出中cut出接口名称和IP地址,同时还进行了一些translate操作(用于去除多余的内容)。


3

嗯,awk一如既往地非常好用。

ip address | 
awk '
    /^[0-9]:/{
        name=substr($2, 1, length($2) - 1)
    }
    /^[ ]*inet /{
        split($2, a, "/")
        if (name != "lo")
            print name,a[1]
    }
'

将输出:

ens32 10.0.0.100
ens33 10.1.0.100
  1. 如果行以数字和双冒号开头,则从第二个字段获取名称,但使用substr删除:
  2. 如果行以inet和空格开头,则第二个参数包含IP地址。我还使用简单的拆分方法删除了掩码后缀。
  3. 如果接口名称为lo,则不打印输出,即过滤回环接口。

1
设置字段分隔符可以简化操作:awk -F'[ :/]+' '/^[0-9]+:/ {name = $2} $2 == "inet" && name != "lo" {print name, $3}' - glenn jackman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接