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

一般的に使用されるいくつかの表記法があります。IPv4そしてIPv6住所これは、一般的に使用されるシンボルをキャプチャするPerlの拡張正規表現ですm//x。コメントとスペースを削除すると、または拡張正規表現(ERE)を使用する他のユーティリティとgrep -E一緒に使用できます。awk

^(
  ([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
)$

10進値の場合は、追加の範囲チェックを実行する必要があります(正規表現を使用することもできますが、膨大です)。

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

バッシュから:

有効なIP4()
{
    IFS='.' na nb nc nd を読み込みます。
    "$na" "$nb" "$nc" "$nd"のnについて。
    する
        [[ ${#n} -le 3 ]] && [[ "${n//[^0-9]/}" = "$n" ]] && [[ $n -lt 256 ]] || 1;
    完璧
    エコOK
}

使用例:

  • 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."

Gilesが指摘したように、これは最も人気がありますドットで区切られた10進表記IPv4 アドレス。

IPv6も同様に行うことができますが、(1)16進数を使用し、(2)すべてがゼロの部分の一部を完全に省略できるため、より多くの確認が必要です。

答え3

ザイルズ延長回答、彼の正規表現はActiveState Perl(バージョン5.20.3、Windows 7/64)では動作しません。 ~によるとここ、パターンの数量子{num1-num2}をに変更する必要{num1,num2}があります。

Data::Validate::IPPerlサイトにモジュールを追加する必要のないREGEXPを提供していただきありがとうございます。

関連情報