Jakiego wyrażenia regularnego mogę użyć do dopasowania adresu IP?

35

Za pomocą następującej grepskładni chcę dopasować cały adres IP w pliku (ze kshskryptu)

  grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' file

Problem: pasuje również do słów (IP), które mają więcej niż 4 oktety:

1.1.1.1.1 

lub

192.1.1.1.160

Jak mogę dopasować prawidłowy adres IP i tylko adresy IP z 4 oktetami? Mogę również użyć Perla - jedno liniowego rozwiązania składni, jeśli grepnie działa.

Jennifer
źródło
4
To też będzie pasować 999.999.999.999.
cyr
4
Chcesz tylko grepować adresy IPv4, prawda ?
Arjan
5
Technicznie, adresy IP takie jak 192.1.4097są prawidłowe i akceptowane przez glibc Linux i Windows.
grawity
1
Ach, nigdy nie wiedziałem ! ping 2130706433Na OS X: PING 2130706433 (127.0.0.1): 56 data bytes.
Arjan
1
@Arjan: 0x7f.1i0177.1
grawity

Odpowiedzi:

56

Spróbuj tego:

grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/hosts

który pasuje do wszystkich wyrażeń od 0.0.0.0do999.999.999.999

z

grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/hosts

dostaniesz tylko adresy IP

Uwaga:
na Solaris prawdopodobnie egrep wykona zadanie.

udo
źródło
Próbuję grep '\ b \ d {1,3} \. \ D {1,3} \. \ D {1,3} \. \ D {1,3} \ b' / etc / hosts, ale ja nic nie dostaję - :(
jennifer
1
@jennifer, musisz włączyć rozszerzone wyrażenia regularne: grep -E <pattern> <file>(lub, aby po prostu wydrukować dopasowania:grep -Eo <pattern> <file>
Arjan
lubię to ? grep -E '\ b \ d {1,3} \. \ d {1,3} \. \ d {1,3} \. \ d {1,3} \ b' / etc / hosts
Jennifer
3
@udo: Cóż, to pasuje, 1.1.1.1.1ale ukrywa ostatnią .1z danych wyjściowych, nie widzę, jak to może pomóc.
crus
1
Twoje wyrażenie regularne nie pasuje do 10.0.0.1
Stefan Seidel,
10

Jak to jest:

perl -MRegexp::Common=net -ne '/($RE{net}{IPv4})/ and print "$1\n"' /etc/hosts
Joe Casadonte
źródło
Miły! (To również zwraca 192.1.1.1.160as 192.1.1.1, co moim zdaniem jest w porządku dla pytającego.)
Arjan
2
Jeśli naprawdę potrzebne są zgodne adresy IP, jest to jedyny rodzaj rozwiązania, które ma szansę być blisko ukończenia. Kiedy zobaczyłem to pytanie, pomyślałem: „Nie dotknę tego standardowym słupem regexp o długości 10 stóp”. Zastrzeżenia, zastrzeżenia wszędzie :-).
Daniel Andersson,
5

The

-w / --word-regexp 

flaga, aby grepdopasować ją tylko na granicach słów, co oznacza, że ​​twoje dopasowanie musi być otoczone białymi spacjami lub początkiem / końcem na początku / końcu linii!

Dominik George
źródło
5

Aby znaleźć dopasowania dokładnie z 4 oktetami (z wyjątkiem rzeczy takich jak 1.1.1.1.1), użyj tego:

grep -P '(?<=[^0-9.]|^)[1-9][0-9]{0,2}(\.([0-9]{0,3})){3}(?=[^0-9.]|$)'

Nigdy nie powinien wykrywać adresów innych niż IP. Wyrażenie może być bardziej złożone, aby zweryfikować więcej rzeczy, ale powinno to działać w większości przypadków. Nie będzie pasować do poprzedniego 0, ponieważ 010.1.12.1 nie jest powszechnym sposobem zapisywania adresów IP.

Stefan Seidel
źródło
5
if [ ` echo $ip | '^((25[0-5]|2[0-4][0-9]|[01]?[1-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[1-9][0-9]?)$'  | grep -o "\." | wc -l` -eq 1 ];
then ipv4=true;
else 
ipv4=false;
Arnaud B.
źródło
3

Trochę trudne, ale powinno działać:

( X='\([0-9]\{1,2\}\|1[0-9]\{2\}\|2[0-4][0-9]\|25[0-5]\)' ; grep "\([^\.]\|^\)$X\.$X\.$X\.$X\([^\.]\|$\)" file )
Cyrus
źródło
Co 127.000.000.001wtedy? ;-)
Arjan
O ile wiem, adresy IP nie mają zer wypełniających.
cyr
1
Hmmm, z ping 127.000.000.001pewnością działa na moim Macu. Ale potem: właśnie się dowiedziałem, że ping 2130706433daje to ten sam rezultat. :-) Ups, ping 00127.00000.00000.00001przekłada się na 87.0.0.1. Dziwne ... A może ósemkowe? Tak, ósemkowe na pewno, więc myślę, że masz rację co do zer wiodących.
Arjan
Tak, 00127 (ósemkowy) = 87 (dziesiętny). Na pewno są to wszystkie prawidłowe adresy IP, ale chyba nie jest to standardowy sposób ich reprezentowania. W każdym razie to nie jest wymagane przez pytającego.
cyr
0

grep -E '^ ((25 [0-5] | 2 [0-4] [0-9] | [1]? [1-9] [0-9]?).) {3} (25 [ 0-5] | 2 [0-4] [0-9] | [1]? [1-9]? [0-9]) $ '

Zmodyfikowana wersja odpowiedzi Arnauda B.

To wyrażenie nie będzie pasowało do adresów IP z wiodącymi zerami. np. nie będzie pasować 192.168.1.01 To wyrażenie nie będzie pasowało do adresów IP zawierających więcej niż 4 oktety. np. nie będzie pasować 192.168.1.2.3

Tomasz
źródło
To również nie będzie pasować do 127.0.0.1.
Chris Charabaruk
0

Używam egrep "^([0-9]{1,3}\.){3}[0-9]{1,3}" /etc/hosts do dopasowania adresów IP na początku linii. Można go również używać bez ^znaku spacji lub innych znaków przed adresem IP.

[0-9]{1,3} --> this matches a number between 1 and 999.
\. --> this is to add the dot.
([0-9]{1,3}\.){3} --> get a number with a dot 3 times.
[0-9]{1,3} --> finally add the fourth number.
Falk
źródło
0

Krótsza wersja długiego wyrażenia regularnego:

egrep '([1-2]?[0-9]{0,2}\.){3,3}[1-2]?[0-9]{0,2}' 

Użyj grep -E lub egrep, odpowiednio do twojej wersji systemu operacyjnego

Suhail
źródło
2
witamy u superużytkownika. To pytanie ma już kilka dobrych odpowiedzi. Aby pomóc ludziom w zrozumieniu różnic między nimi, edytuj swoją odpowiedź i wyjaśnij, co czyni ją lepszą / różni się od innych.
Máté Juhász
to wyrażenie nie uwzględnia takich legalnych wartości IP jak 8.8.8.8 echo "8.8.8.8" | grep -Eo '([1-2][0-9]{0,2}\.){3,3}[1-2][0-9]{0,2}'=> brak wyników
anneb
0

grep -Eo '([0-9] {1,3}.?) {4} ”

Przykład: curl http://korben.info/ip | grep "IP widoczny depuis mon servur" | grep -Eo '([0-9] {1,3}.?) {4} ”

użytkownik2357585
źródło
0

Wyrażenie regularne dla dopasowania adresu IP w TCL

ustaw „192.168.10.25”

if {[regexp
{^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$} $a]} 
{
    puts "yes"
}
abhilash.malla
źródło
-1

Oto, co działało dla mnie dla ksh i ksh93 w systemie AIX:

ip =

[[$ ip == [0-9] @ ("" | [0-9]) @ ("" | [0-9]). [0-9] @ ("" | [0-9]) @ ("" | [0-9]). [0-9] @ ("" | [0-9]) @ ("" | [0-9]). [0-9] @ ("" | [0-9]) @ („” | [0-9])]] && echo OK || echo NOK Powyższe informacje można zmodyfikować w celu „przefiltrowania” podanego adresu IP do dowolnego pożądanego wzoru.

Niko
źródło