将网络掩码应用于 IP 地址的一般情况:

将网络掩码应用于 IP 地址的一般情况:

我的字符串(IP 地址)中有以下模式:

123.444.888.235

我想用 替换点后的最后一个数字0,所以它变成:

123.444.888.0

我怎样才能用bash或其他 shell 脚本语言来做到这一点?

答案1

在任何 POSIX shell 中:

var=123.444.888.235
new_var="${var%.*}.0"

${var%pattern}ksh是80 年代引入的运算符,由 POSIX 针对标准sh语言进行标准化,现在由解释该语言的所有 shell 实现,包括bash.

${var%pattern}$var扩展为stripped 的最短匹配字符串的内容图案离开它的末尾(或者就像$var那样图案不匹配)。所以${var%.*}(哪里.*图案这意味着点后跟任意数量的字符)扩展到$var没有最右边.及其后面的内容。相比之下,${var%%.*}其中最长与被剥离模式匹配的字符串将扩展为$var没有最左边.及其后面的内容。

答案2

这应该有效。

echo 123.444.888.235 | sed 's/\([0-9]*\.[0-9]*\.[0-9]*\.\)[0-9]*/\10/'

请注意,最后一个sed替换字段\10是第一个匹配的模式 ( \1),与文字零连接。

答案3

将网络掩码应用于 IP 地址的一般情况:

假设你输入的是 IP 地址,并且你用 替换该地址的最后一个八位字节.0,那么我假设你是真的试图实现的是使用网络掩码来计算 IP 地址的网络部分255.255.255.0

如果您的网络掩码长度可以被 8 整除,则只需用零替换八位字节就可以了,但这不是一般情况。如果您需要对任何有效(子网)网络掩码执行此操作,那么您可以执行以下操作:

function d2i() {
    echo $(( 0x$( printf "%02x" ${1//./ } ) ))
}

function i2d() {
    h=$( printf "%08X" "$1" )
    echo $(( 0x${h:0:2} )).$(( 0x${h:2:2} )).$(( 0x${h:4:2} )).$(( 0x${h:6:2} ))
}

function ipmask() {
    i2d $(( $( d2i $1 ) & $( d2i $2 ) ))
}

ipmask 123.44.88.235 255.255.255.0     # outputs 123.44.88.0
ipmask 123.44.88.235 255.255.255.240   # outputs 123.44.88.224

这定义了 3 个函数:

  • d2i()将 IP 地址(或掩码)的点分十进制形式转换为简单整数
  • i2d()执行相反的操作 - 将简单整数转换为点分十进制
  • ipmask()只需计算地址和网络掩码的按位与即可给出地址的网络部分。 Bash 期望 的操作数&是整数。

这两个调用展示了ipmask如何根据两个不同掩码的 IP 地址计算网络。


请注意,如问题中所述,123.444.888.235是无效的 IP 地址。我已经用123.44.88.235这些例子来代替。

答案4

另一种sed答案:

sed -r 's/(.*\.).*/\10/'

它将所有内容分组到最后一个点,并将整行替换为该组的内容,后跟 0。
我使用 -r 来避免必须转义括号。

相关内容