Linux 셸에서 정규식을 사용하여 파일에서 IP 주소를 어떻게 추출합니까?
Linux 쉘에서 regexp로 텍스트 부분을 추출하는 방법은 무엇입니까? 모든 줄에 IP 주소가 있지만 다른 위치에있는 파일이 있다고 가정 해 보겠습니다. 일반적인 Unix 명령 줄 도구를 사용하여 이러한 IP 주소를 추출하는 가장 간단한 방법은 무엇입니까?
grep 을 사용 하여 빼낼 수 있습니다.
grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' file.txt
여기에있는 대부분의 예는 기술적으로 유효한 IP 주소가 아닌 999.999.999.999에서 일치합니다.
다음은 유효한 IP 주소 (네트워크 및 브로드 캐스트 주소 포함)에서만 일치합니다.
grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' file.txt
일치하는 전체 행을 보려면 -o를 생략하십시오.
이것은 액세스 로그에서 잘 작동합니다.
cat access_log | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'
부분별로 나누어 봅시다.
[0-9]{1,3}
[]에 언급 된 범위의 1 ~ 3 개 발생을 의미합니다. 이 경우 0-9입니다. 따라서 10 또는 183과 같은 패턴과 일치합니다.뒤에 '.'가 붙습니다. '.'로 이스케이프해야합니다. 메타 문자이며 쉘에 대해 특별한 의미가 있습니다.
이제 우리는 '123'과 같은 패턴에 있습니다. '12. ' 기타
이 패턴은 '.'와 함께 세 번 반복됩니다. 그래서 우리는 그것을 괄호로 묶습니다.
([0-9]{1,3}\.){3}
그리고 마지막으로 패턴이 반복되지만 이번에는 '.'가 없습니다. 그래서 3 단계에서 따로 보관했습니다.
[0-9]{1,3}
내 경우와 같이 ips가 각 줄의 시작 부분에 있으면 다음을 사용하십시오.
egrep -o '^([0-9]{1,3}\.){3}[0-9]{1,3}'
여기서 '^'는 줄의 시작 부분을 검색하도록 지시하는 앵커입니다.
나는 보통 정규 표현식을 올바르게 얻기 위해 grep으로 시작합니다.
# [multiple failed attempts here]
grep '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' file # good?
grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' file # good enough
그런 다음 sed
나머지 줄을 필터링 하기 위해 로 변환하려고 합니다. (이 스레드를 읽은 후, 당신과 나는 더 이상 그렇게하지 않을 것입니다. grep -o
대신 사용할 것입니다.)
sed -ne 's/.*\([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\).*/\1/p # FAIL
sed
다른 사람과 동일한 정규식을 사용하지 않아서 보통 짜증 이납니다. 그래서 나는 perl
.
$ perl -nle '/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/ and print $&'
Perl은 어떤 경우에도 알아두면 좋습니다. 약간의 CPAN이 설치되어 있으면 적은 비용으로 더 안정적으로 만들 수도 있습니다.
$ perl -MRegexp::Common=net -nE '/$RE{net}{IPV4}/ and say $&' file(s)
로그 파일을 더 잘보기 위해 약간의 스크립트 를 작성했습니다. 특별한 것은 아니지만 펄을 배우는 많은 사람들에게 도움이 될 수 있습니다. IP 주소를 추출한 후 DNS 조회를 수행합니다.
sed 를 사용할 수 있습니다 . 하지만 펄을 알고 있다면 장기적으로 아는 것이 더 쉽고 유용 할 수 있습니다.
perl -n '/(\d+\.\d+\.\d+\.\d+)/ && print "$1\n"' < file
내가 만든 쉘 도우미를 사용할 수 있습니다 : https://github.com/philpraxis/ipextract
편의를 위해 여기에 포함 :
#!/bin/sh
ipextract ()
{
egrep --only-matching -E '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
}
ipextractnet ()
{
egrep --only-matching -E '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/[[:digit:]]+'
}
ipextracttcp ()
{
egrep --only-matching -E '[[:digit:]]+/tcp'
}
ipextractudp ()
{
egrep --only-matching -E '[[:digit:]]+/udp'
}
ipextractsctp ()
{
egrep --only-matching -E '[[:digit:]]+/sctp'
}
ipextractfqdn ()
{
egrep --only-matching -E '[a-zA-Z0-9]+[a-zA-Z0-9\-\.]*\.[a-zA-Z]{2,}'
}
쉘에서로드 / 소스 (ipextract 파일에 저장 될 때) :
$. ipextract
그것을 써:
$ ipextract < /etc/hosts
127.0.0.1
255.255.255.255
$
실제 사용의 예 :
ipextractfqdn < /var/log/snort/alert | sort -u
dmesg | ipextractudp
grep -E -o "([0-9] {1,3} [.]) {3} [0-9] {1,3}"
이 주제에 대한 유익한 블로그 기사를 작성했습니다 . Regex를 사용하여 일반 텍스트에서 IPv4 및 IPv6 IP 주소를 추출하는 방법 .
이 기사에는 정규 표현식을 사용하여 일반 텍스트에서 추출하고 분리해야하는 가장 일반적인 IP 패턴에 대한 자세한 가이드가 있습니다.
이 가이드는 필요한 경우 IP 주소 추출 및 감지를 처리하기위한 CodVerter의 IP 추출기 소스 코드 도구를 기반으로 합니다.
IPv4 주소를 확인하고 캡처하려는 경우이 패턴이 작업을 수행 할 수 있습니다.
\b(?:(?: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]?)\b
또는 접두사가있는 IPv4 주소의 유효성을 검사하고 캡처하려면 ( "슬래시 표기법") :
\b(?:(?: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]?/[0-9]{1,2})\b
또는 서브넷 마스크 또는 와일드 카드 마스크를 캡처하려면 :
(255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)
또는 서브넷 마스크 주소를 필터링하려면 regex negative lookahead로 수행합니다 .
\b((?!(255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)[.](255|254|252|248|240|224|192|128|0)))(?:(?: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]?)\b
대한 의 IPv6 검증 당신은 내가이 답변의 상단에 추가 한 문서 링크로 이동 할 수 있습니다.
다음은 모든 공통 패턴을 캡처하는 예입니다 (CodVerter의 IP 추출기 도움말 샘플에서 가져옴).
원하는 경우 여기 에서 IPv4 정규식을 테스트 할 수 있습니다 .
아파치 로그에서 IP 주소를 가져오고 IP 주소가 웹 사이트를 방문한 횟수를 나열하기위한 준비된 솔루션을 원하는 사람들을 위해 다음 줄을 사용하십시오.
grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' error.log | sort | uniq -c | sort -nr > occurences.txt
해커를 차단하는 좋은 방법입니다. 다음으로 다음을 수행 할 수 있습니다.
- 방문수가 20 회 미만인 줄 삭제
- 정규식을 사용하여 단일 공간까지 잘라내어 IP 주소 만 갖습니다.
- 정규 표현식을 사용하면 IP 주소의 마지막 1-3 개를 잘라서 네트워크 주소 만 갖게됩니다.
- Add
deny from
and a space at the beginning of each line - Put the result file as .htaccess
I'd suggest perl. (\d+.\d+.\d+.\d+) should probably do the trick.
EDIT: Just to make it more like a complete program, you could do something like the following (not tested):
#!/usr/bin/perl -w
use strict;
while (<>) {
if (/(\d+\.\d+\.\d+\.\d+)/) {
print "$1\n";
}
}
This handles one IP per line. If you have more than one IPs per line, you need to use the /g option. man perlretut gives you a more detailed tutorial on regular expressions.
You could use awk, as well. Something like ...
awk '{i=1; if (NF > 0) do {if ($i ~ /regexp/) print $i; i++;} while (i <= NF);}' file
-- may need cleaning. just a quick and dirty response to show basically how to do it with awk
All of the previous answers have one or more problems. The accepted answer allows ip numbers like 999.999.999.999. The currently second most upvoted answer requires prefixing with 0 such as 127.000.000.001 or 008.008.008.008 instead of 127.0.0.1 or 8.8.8.8. Apama has it almost right, but that expression requires that the ipnumber is the only thing on the line, no leading or trailing space allowed, nor can it select ip's from the middle of a line.
I think the correct regex can be found on http://www.regextester.com/22
So if you want to extract all ip-adresses from a file use:
grep -Eo "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])" file.txt
If you don't want duplicates use:
grep -Eo "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])" file.txt | sort | uniq
Please comment if there still are problems in this regex. It easy to find many wrong regex for this problem, I hope this one has no real issues.
Everyone here is using really long-handed regular expressions but actually understanding the regex of POSIX will allow you to use a small grep
command like this for printing IP addresses.
grep -Eo "(([0-9]{1,3})\.){3}([0-9]{1,3})"
(Side note) This doesn't ignore invalid IPs but it is very simple.
I have tried all answers but all of them had one or many problems that I list a few of them.
- Some detected
123.456.789.111
as valid IP - Some don't detect
127.0.00.1
as valid IP - Some don't detect IP that start with zero like
08.8.8.8
So here I post a regex that works on all above conditions.
Note : I have extracted more than 2 millions IP without any problem with following regex.
(?:(?:1\d\d|2[0-5][0-5]|2[0-4]\d|0?[1-9]\d|0?0?\d)\.){3}(?:1\d\d|2[0-5][0-5]|2[0-4]\d|0?[1-9]\d|0?0?\d)
If you are not given a specific file and you need to extract IP address then we need to do it recursively. grep command -> Searches a text or file for matching a given string and displays the matched string .
grep -roE '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}' | grep -oE '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}'
-r -> We can search the entire directory tree i.e. the current directory and all levels of sub-directories. It denotes recursive searching.
-o -> Print only the matching string
-E -> Use extended regular expression
If we would not have used the second grep command after the pipe we would have got the IP address along with the path where it is present
cat ip_address.txt | grep '^[0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}[,].*$\|^.*[,][0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}[,].*$\|^.*[,][0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}[.][0-9]\{1,3\}$'
Lets assume the file is comma delimited and the position of ip address in the beginning ,end and somewhere in the middle
첫 번째 정규 표현식은 줄 시작 부분에서 정확히 일치하는 IP 주소를 찾습니다. or 뒤의 두 번째 정규 표현식은 중간에서 ip 주소를 찾습니다. 우리는 뒤에 오는 숫자가 정확히 1 ~ 3 자리 여야합니다.
세 번째 정규 표현식은 줄 끝에서 IP 주소를 찾습니다.
디렉토리의 모든 파일에서 "10"으로 시작하는 IP 주소 만 가져오고 싶었습니다.
grep -o -nr "[10]\{2\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" /var/www
centos6.3 용
ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | awk 'BEGIN {FS=":"} {print $2}'
'IT TIP' 카테고리의 다른 글
Rails, 모델에서 뷰 / 부분을 렌더링하는 방법 (0) | 2020.12.09 |
---|---|
bower 프록시 구성 (0) | 2020.12.09 |
jquery 데이터 테이블 숨기기 열 (0) | 2020.12.09 |
iOS : 기기가 회전 한 후 기능을 실행하는 방법 (Swift) (0) | 2020.12.09 |
인증 플러그인 'caching_sha2_password'를로드 할 수 없음 문제 해결 방법 (0) | 2020.12.09 |