替换 IP 地址和空格

Replacing IP addresses and spaces

我正在尝试转换 ifconfig -a 以提供特定的输出,但我不确定 sed 是否运行良好。有可能特定版本的 sed 没有正常运行(由于不同的 sed 版本)。

我的ifconfig -a输出(我只想看网络掩码):

    xennet0: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST> mtu 1500
            capabilities=2800<TCP4CSUM_Tx,UDP4CSUM_Tx>
            enabled=0
            address: 0a:3d:c0:98:c6:73
            inet 172.31.11.166 netmask 0xfffff000 broadcast 172.31.15.255
            inet6 fe80::83d:c0ff:fe98:c673%xennet0 prefixlen 64 scopeid 0x1
    lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33184
            inet 127.0.0.1 netmask 0xff000000
            inet6 ::1 prefixlen 128
            inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2

需要的输出(转换后的输出):

 0xfffff000
 0xff000000

我失败的尝试:

ifconfig -a | egrep "0xf." | sed 's/inet //' | sed 's/netmask //' |
sed 's/ broadcast//' | sed 's/([0-9]{1,3}\.){3}[0-9]{1,3}//g' | sed 's/\s+//'

它给我的输出为:

        172.31.11.166 0xfffff000 172.31.15.255
        127.0.0.1 0xff000000

我希望它能提供我需要的输出。

有帮助会有很大帮助。我正在使用 NetBSD 6.1.5 (Amazon EC2),但是,我相信任何通用的固定装置都应该可以工作。

在某些方面,你太难了。并使用比严格要求更多的命令。这是一个命令行,只需调用一次 sed(1) 即可完成您想要的操作:

ifconfig -a | sed -ne '/inet /s/^.* netmask \(.*\) broadcast.*$//p'

解释:“/inet /”告诉 sed(1) select 仅包含该字符串的行,然后应用表达式的其余部分。表达式的其余部分从关键字 "netmask " 和“broadcast”之间去除网络掩码,并打印结果。

sed(1) 命令行上的“-n”告诉 sed(1) 在检查时不要打印行。 “-e”表示下一个参数是内联 sed(1) 脚本。

根据我的评论,未命中 lo*。

将模式更改为:

'/inet /s/^.* netmask \(0x[0-9a-fA-F]*\).*$//p'

创建所需的结果。 (包括所有接口运行 inet,包括lo*)

将 Grep 与扩展正则表达式结合使用

您可以使用 grep 的 ERE 引擎和 --only-matching 标志来仅提取十六进制值。为此,请使用 egrepgrep -E 打开扩展正则表达式。例如:

$ egrep -o '0x[[:xdigit:]]{8}' /tmp/corpus 
0xfffff000
0xff000000

同样,您也可以通过管道输入输出并获得相同的结果:

$ ifconfig -a | egrep -o '0x[[:xdigit:]]{8}'

这适用于 GNU 和 BSD greps,并且不依赖于 PCRE 库。因此,它应该可以在大多数现代系统上运行,而无需进行任何调整。

使用 GNU grep,我将使用带 -o 选项的 Perl 正则表达式(仅保留匹配项):

$ ifconfig -a | grep -Po '(?<=\bnetmask )\w*'
0xfffff000
0xff000000

对于 BSD grep,我们没有 -P 选项,我们可以使用 awk 或 cut 只获取第二部分,如

$ ifconfig -a | grep -o '\bnetmask [^ ]*' | cut -d ' ' -f 2
0xfffff000
0xff000000

如果你真的想使用 sed,你可以这样做:

$ ifconfig -a | sed -n 's/.*\bnetmask \([^ ]*\).*//p'
0xfffff000
0xff000000

这与 Eric 的回答非常相似。它用 -n 抑制输出,对于包含 netmask 的行,它提取它后面的单词并用(p 标志)打印它。

虽然使用 sed 可能很有趣,但我建议 awk 作为这项(以及任何类似)工作的正确工具:

ifconfig -a | awk '{ for (i = 1; i < NF; i++) {if ($i == "netmask") { print $(i+1); next; } }}'