如何过滤IPv4和IPv6地址?

如何过滤IPv4和IPv6地址?
echo "1.1.1.1" | awk '/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/ {print $1}'

如何在脚本中过滤 IPv4 地址,以及如何过滤 IPv6 地址。

我的意思更准确地说,因此 oneliner 应该只输出有效的 IPv4 地址,或者另一个脚本只输出有效的 IPv6 地址。用不同的语言?比如:awk、perl?

蒂!

答案1

有几种常用的记号IPv4IPv6地址。这是一个适用于 Perl 的扩展正则表达式,m//x它捕获了常用的符号。如果删除注释和空格,则可以将其与grep -Eawk或使用扩展正则表达式 (ERE) 的任何其他实用程序一起使用。

^(
  ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|0+[0-3][0-7][0-7]|0x0*[0-9a-fA-F][0-9a-fA-F])
  (\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]|0+[0-3][0-7][0-7]|0x0*[0-9a-fA-F][0-9a-fA-F])){3}   # IPv4 dotted quad
| 0x[0-9a-fA-F]{1-8}             # IPv4 hexadecimal
| 0+[0-9]{0-10} | 0+[1-3]{11}    # IPv4 octal
| [1-9][0-9]{1-8}                # IPv4 decimal, small
| [1-3][0-9]{9}                  # IPv4 decimal, medium
| 4[0-9]{9}                      # IPv4 decimal, large (needs a further range check)
| [0-9a-fA-F]{1-4}(:[0-9a-fA-F]{1-4}){7}            # IPv6 with all groups
| ([0-9a-fA-F]{1-4}:){1-1}(:[0-9a-fA-F]{1-4}){1-6}  # IPv6 with 1-6 middle groups omitted
| ([0-9a-fA-F]{1-4}:){1-2}(:[0-9a-fA-F]{1-4}){1-5}  # IPv6 with 1-6 middle groups omitted
| ([0-9a-fA-F]{1-4}:){1-3}(:[0-9a-fA-F]{1-4}){1-4}  # IPv6 with 1-6 middle groups omitted
| ([0-9a-fA-F]{1-4}:){1-4}(:[0-9a-fA-F]{1-4}){1-3}  # IPv6 with 1-6 middle groups omitted
| ([0-9a-fA-F]{1-4}:){1-5}(:[0-9a-fA-F]{1-4}){1-2}  # IPv6 with 1-6 middle groups omitted
| ([0-9a-fA-F]{1-4}:){1-6}(:[0-9a-fA-F]{1-4}){1-1}  # IPv6 with 1-6 middle groups omitted
)$

如果是十进制值,您需要进一步进行范围检查(您可以对其进行正则表达式,但它会很大):

if (!/[^0-9]/ && /^[^0]/) { # if it's a decimal number
    die if $_ > 4294967295 # reject numbers above 2^32-1
}

如果您使用的工具只支持32位数字,则只能对以4开头的数字进行测试,并在进行检查之前将4去掉。

if (!/[^0-9]/ && /^4/) { # if it's a decimal number beginning with 4
    my $tmp = $_;
    $tmp =~ s/^4//;
    die if $tmp > 294967295;
}

答案2

在bash中:

有效IP4 ()
{
    IFS='.'读 na nb nc nd;
    对于“$na”“$nb”“$nc”“$nd”中的 n;
        [[ ${#n} -le 3 ]] && [[ "${n//[^0-9]/}" = "$n" ]] && [[ $n -lt 256 ]] ||返回1;
    完毕
    回声确定
}

用法示例:

  • echo 142.24.045.33 | validIP4
  • echo sd3.3.4.6 | validIP4 || echo "nope :("
  • echo 342.0.0.2 | validIP4 || echo "Noo...."
  • echo 3.2.1.0 | validIP4 && echo "Yes, sir."

正如吉尔斯指出的,这仅验证最受欢迎的点十进制表示法IPv4 地址。

IPv6 可以以类似的方式完成,但需要更多检查,因为 (1) 它使用十六进制,并且 (2) 可以完全省略一些全零部分。

答案3

延长吉尔斯的回答,他的正则表达式不适用于 ActiveState Perl(版本 5.20.3,Windows 7/64)。根据这里,模式的量词 from{num1-num2}必须更改为{num1,num2}并且它将起作用。

感谢您提供 REGEXP,它让我无需Data::Validate::IP在 Perl 站点上添加模块。

相关内容