IP 주소와 일치하지 않는 문자열을 가상 IP 주소로 바꾸려면 어떻게 해야 합니까?

IP 주소와 일치하지 않는 문자열을 가상 IP 주소로 바꾸려면 어떻게 해야 합니까?

IP 주소 목록이 포함된 파일이 있지만 일부 문자열은 IP 주소가 아니며 이 문자열을 가상 IP 주소로 바꾸고 싶습니다.

IP를 검색하는 데 사용 grep하지만 가상 IP 주소와 일치하지 않는 항목을 바꾸는 방법을 모르겠습니다. 나는 이것이 를 통해 이루어질 수 있다고 믿습니다 sed. 나는 몇 가지를 시도했지만 그 중 아무것도 작동하지 않았습니다.

cat file.txt | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'

파일에서 IP 주소를 일치시키는 데 사용하고 있지만 sedIP가 아닌 주소를 가상 IP로 바꾸는 방법을 모르겠습니다.

sed -rn '/([0-9]{1,3}\.){3}[0-9]{1,3}/p' file.txt

입력하다:

192.168.10.20
00 03
10.28.214.5
192.168.10.40
BF
192.168.10.50

원하는 출력:

192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50

감사해요!

답변1

정규식은 다음과 일치합니다.아니요IPv4는 4개의 주소 그룹에 점을 찍지만 유사해 보입니다(예를 들어 256.256.256.256IPv4 주소처럼 보이지만 그렇지 않습니다).

일치만효과적인IPv4 주소의 경우 정규식을 사용해야 합니다. 예:

(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

또는 (Perlish ?:비캡처 그룹 수정자 제외):

((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

^이를 위해서는 and $, 또는 and를 양쪽 끝에 사용하는 등 적절한 앵커링이 필요합니다 .\b\<\>

바라보다:정규식 레시피저자: Jan Goyvaerts 및 Steven Levithan 출판사: O'Reilly Media, Inc.

예를 들어

$ sed -E '/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/!s/.*/192.168.0.0/' file.txt 
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50
$ perl -p -e 's/.*/192.168.0.0/ unless m/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/' file.txt 
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50

이 두 가지 모두 라인이 유효한 IPv4 주소와 일치하지 않는 한 전체 입력 라인을 192.168.0.0으로 변경합니다.

개인적으로 나는 Perl을 사용하고 싶습니다정규식::공통모듈은 일반적인 패턴 일치 작업을 위한 대규모 정규식 모음으로, 이름으로 편리하게 사용할 수 있습니다 %RE.

$ perl -MRegexp::Common -p -e 's/.*/192.168.0.0/ unless m/^$RE{net}{IPv4}$/' file.txt 
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50

답변2

참고: 다른 사람들은 IPv4 주소에 대해 선택한 정규식에 결함이 있다고 지적했습니다. 이 문제는 다른 곳에서 잘 다루어졌으므로 여기서는 다루지 않겠습니다.

당신은 sed를 사용할 수 있습니다RE( )와 일치하지 않는 !행에서 hange 명령을 실행하십시오 .

$ sed -r '/([0-9]{1,3}\.){3}[0-9]{1,3}/!c\
192.168.0.0
' file.txt
192.168.10.20
192.168.0.0
10.28.214.5
192.168.10.40
192.168.0.0
192.168.10.50

GNU sed를 사용하면 다음과 같이 단순화할 수 있습니다.

sed -r '/([0-9]{1,3}\.){3}[0-9]{1,3}/!c192.168.0.0' file.txt

답변3

sed '/^\([[:digit:]]\{1,3\}\.\)\{3\}[[:digit:]]\{1,3\}$/!s/.*/192.168.0.0/' data

줄이 유효한 IPv4 주소가 아닌 경우 현재 줄을 다음으로 바꿉니다 192.168.0.0.

가상 주소에 다른 값을 사용하는 것이 좋지만 192.168.0.0이는 귀하와 귀하의 필요에 달려 있습니다.

또는 동일하지만 다음과 같습니다 awk.

awk '!/^([0-9]{1,3}\.){3}[0-9]{1,3}$/ {$0="192.168.0.0"}1' data

또는 perl:

perl -MNet::IP -ple '$_ = "192.168.0.0" unless new Net::IP($_)' data

답변4

그리고 Perl:

  • 1~3자리 숫자로 구성된 옥텟을 정의하는 정규 표현식으로, 한 자리 숫자가 아닌 이상 앞에 0이 아닌 숫자로 제한됩니다.
  • 점으로 구분된 정확히 4개의 옥텟을 포함하는 행과 일치합니다.
  • 라인을 포인트로 분할하면 모든 튜플이 256보다 작습니다.
dummy=192.168.0.0 \
perl -MList::Util=all -lpe '
  $octet //= qr/(?!0\d)\d{1,3}/;

  /^$octet(?:[.]$octet){3}$/ &&
   all { $_<256 } split /[.]/ or
     $_ = $ENV{dummy};
' file

관련 정보