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
)$

십진수 값인 경우 추가 범위 확인을 수행해야 합니다(정규식을 사용할 수도 있지만 엄청날 것입니다).

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가 지적했듯이 이는 가장 인기 있는점으로 구분된 십진수 표기법IPv4 주소.

IPv6도 비슷한 방식으로 수행할 수 있지만 (1) 16진수를 사용하고 (2) 모두 0인 부분 중 일부를 완전히 생략할 수 있기 때문에 더 많은 확인이 필요합니다.

답변3

자일스 연장'답변, 그의 정규식은 ActiveState Perl(버전 5.20.3, Windows 7/64)에서 작동하지 않습니다. ~에 따르면여기, 패턴의 수량자를 {num1-num2}으로 변경해야 {num1,num2}작동합니다.

Data::Validate::IPPerl 사이트에 모듈을 추가할 필요가 없는 REGEXP를 제공해 주셔서 감사합니다 .

관련 정보