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 주소를 일치시키는 데 사용하고 있지만 sed
IP가 아닌 주소를 가상 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.256
IPv4 주소처럼 보이지만 그렇지 않습니다).
일치만효과적인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