Quale espressione regolare posso usare per abbinare un indirizzo IP?


35

Con la seguente grepsintassi voglio abbinare tutto l'indirizzo IP in un file (da uno kshscript)

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

Il problema: corrisponde anche a parole (IP) che hanno più di 4 ottetti:

1.1.1.1.1 

o

192.1.1.1.160

Come posso abbinare un IP valido e solo indirizzi IP a 4 ottetti? Posso anche usare Perl, una soluzione di sintassi a una riga, se grepnon funziona.


4
Abbinerà 999.999.999.999anche.
cYrus

4
Quindi, vuoi solo grep indirizzi IPv4, giusto ?
Arjan,

5
Tecnicamente, indirizzi IP come 192.1.4097sono validi e accettati da Linux glibc e Windows.
gravità

1
Ah, non l'ho mai saputo ! ping 2130706433, Su OS X: PING 2130706433 (127.0.0.1): 56 data bytes.
Arjan,

1
@Arjan: 0x7f.1e0177.1
gravità

Risposte:


56

prova questo:

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

che corrisponde a tutte le espressioni da 0.0.0.0a999.999.999.999

con

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

otterrai solo indirizzi IP

nota:
su Solaris probabilmente egrep farà il lavoro.


Provo il grep '\ b \ d {1,3} \. \ D {1,3} \. \ D {1,3} \. \ D {1,3} \ b' / etc / hosts ma io non ottenere nulla - :(
jennifer

1
@jennifer, devi abilitare le espressioni regolari estese: grep -E <pattern> <file>(o, per stampare solo le partite:grep -Eo <pattern> <file>
Arjan

come questo ? grep -E '\ b \ d {1,3} \. \ d {1,3} \. \ d {1,3} \. \ d {1,3} \ b' / etc / hosts
jennifer

3
@udo: Beh, questo corrisponde 1.1.1.1.1ma nasconde l'ultimo .1dall'output, non riesco a vedere come può aiutare.
cYrus,

1
Il tuo regexp non corrisponde a 10.0.0.1
Stefan Seidel,

10

Com'è questo:

perl -MRegexp::Common=net -ne '/($RE{net}{IPv4})/ and print "$1\n"' /etc/hosts

Bello! (Anche questo ritorna 192.1.1.1.160come 192.1.1.1, che penso vada bene per l'interrogativo.)
Arjan

2
Se si vogliono davvero indirizzi IP conformi, questo è l'unico tipo di soluzione che ha qualche possibilità di essere vicino al completamento. Quando ho visto la domanda, ho pensato "Non lo toccherò con un palo regexp standard di dieci piedi". Avvertenze, avvertenze ovunque :-).
Daniel Andersson,

5

Il

-w / --word-regexp 

flag per grepfar corrispondere solo i confini delle parole, il che significa che la tua corrispondenza deve essere circondata da spazi bianchi o iniziare / finire all'inizio / fine della linea!


5

Per trovare esattamente solo le partite con 4 ottetti (escludendo cose come 1.1.1.1.1) usa questo:

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

Non dovrebbe mai rilevare indirizzi non IP. L'espressione potrebbe essere più complessa per verificare più cose, ma dovrebbe funzionare nella maggior parte dei casi. Non corrisponderà a uno 0 precedente poiché 010.1.12.1 non è un modo comune per scrivere indirizzi IP.


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;

3

Un po 'complicato, ma dovrebbe funzionare:

( X='\([0-9]\{1,2\}\|1[0-9]\{2\}\|2[0-4][0-9]\|25[0-5]\)' ; grep "\([^\.]\|^\)$X\.$X\.$X\.$X\([^\.]\|$\)" file )

E 127.000.000.001allora? ;-)
Arjan,

Per quanto ne so, gli IP non hanno zeri di riempimento.
cYrus

1
Hmmm, ping 127.000.000.001sicuramente funziona sul mio Mac. Ma poi: ho appena imparato che ping 2130706433produce lo stesso risultato. :-) Oops, si ping 00127.00000.00000.00001traduce in 87.0.0.1. Strano ... O forse ottale? Sì, ottale di sicuro, quindi hai ragione sui primi zero immagino.
Arjan,

Sì, 00127 (ottale) = 87 (decimale). Sicuramente sono tutti IP validi, ma suppongo che non sia il modo standard di rappresentarli. Comunque ciò non è richiesto dal richiedente.
cYrus

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

Versione modificata della risposta di Arnaud B.

Questa espressione non corrisponderà agli indirizzi IP con 0 iniziali. ad esempio, non corrisponderà a 192.168.1.01 Questa espressione non corrisponderà agli indirizzi IP con più di 4 ottetti. ad esempio, non corrisponderà a 192.168.1.2.3


Neanche questo corrisponderà a 127.0.0.1.
Chris Charabaruk,

0

Sto usando egrep "^([0-9]{1,3}\.){3}[0-9]{1,3}" /etc/hosts per abbinare gli indirizzi IP all'inizio di una riga. Può anche essere utilizzato senza ^consentire spazi bianchi o altri caratteri prima dell'indirizzo 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.

0

Una versione più breve del regex lungo:

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

Si prega di utilizzare grep -E o egrep come adatto alla versione del proprio sistema operativo


2
benvenuto al superutente. Questa domanda ha già diverse buone risposte. Per aiutare le persone a comprendere le differenze tra loro, modifica la tua risposta e spiega cosa la rende migliore / diversa dalle altre.
Máté Juhász,

questa espressione non tiene conto di IP legali come 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}'=> nessun risultato
anneb


0

Espressione regolare per la corrispondenza di un indirizzo IP in TCL

imposta un "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"
}

-1

Ecco cosa ha funzionato per me per ksh e ksh93 in 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 Quanto sopra può essere modificato al fine di "filtrare" l'IP fornito in base a qualsiasi modello sia desiderato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.