Quelle expression régulière puis-je utiliser pour faire correspondre une adresse IP?

35

Avec la grepsyntaxe suivante, je veux faire correspondre toutes les adresses IP d'un fichier (à partir d'un kshscript)

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

Le problème: il correspond également aux mots (IP) de plus de 4 octets:

1.1.1.1.1 

ou

192.1.1.1.160

Comment faire correspondre une adresse IP valide et uniquement des adresses IP de 4 octets? Je peux aussi utiliser Perl - une solution de syntaxe sur une ligne, si grepcela ne fonctionne pas.

Jennifer
la source
4
Cela va correspondre 999.999.999.999aussi.
cYrus
4
Donc, vous voulez seulement grep des adresses IPv4, non ?
Arjan
5
Techniquement, les adresses IP telles que 192.1.4097valides et acceptées par Linux glibc et Windows.
Grawity
1
Ah, je n'ai jamais su ! ping 2130706433, Sur OS X: PING 2130706433 (127.0.0.1): 56 data bytes.
Arjan
1
@Arjan: 0x7f.1et0177.1
grawity

Réponses:

56

essaye ça:

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

qui correspond à toutes les expressions de 0.0.0.0à999.999.999.999

avec

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

vous obtiendrez des adresses IP seulement

note:
sur solaris probablement egrep fera le travail.

tu fais
la source
J'essaie le grep '\ b \ d {1,3} \. \ D {1,3} \. \ D {1,3} \. \ D {1,3} \ b' / etc / hosts mais je ne rien obtenir - :(
jennifer
1
@ jennifer, vous devez activer les expressions rationnelles étendues: grep -E <pattern> <file>(ou, pour simplement imprimer les correspondances:grep -Eo <pattern> <file>
Arjan
comme ça ? grep -E '\ b \ d {1,3} \. \ d {1,3} \. \ d {1,3} \. \ d {1,3} \ b' / etc / hosts
jennifer
3
@udo: Eh bien, cela correspond 1.1.1.1.1mais le dernier masque .1de la sortie, je ne vois pas en quoi cela peut aider.
cYrus
1
Votre expression rationnelle ne correspond pas à 10.0.0.1
Stefan Seidel le
10

Comment c'est:

perl -MRegexp::Common=net -ne '/($RE{net}{IPv4})/ and print "$1\n"' /etc/hosts
Joe Casadonte
la source
Agréable! (Ceci retourne aussi 192.1.1.1.160comme 192.1.1.1, ce qui, à mon avis, convient à l'interrogateur.)
Arjan
2
Si des adresses IP conformes sont vraiment recherchées, il s’agit du seul type de solution susceptible d’être achevée. Quand j’ai vu la question, j’ai juste pensé: «Je ne vais pas y toucher avec un mât regexp standard de 10 pieds». Mises en garde, mises en garde partout :-).
Daniel Andersson le
5

le

-w / --word-regexp 

flag to grepfait en sorte qu’il ne corresponde qu’aux limites de mots, ce qui signifie que votre correspondance doit être entourée d’espaces ou bien commencer / terminer au début / à la fin de la ligne!

Dominik George
la source
5

Pour ne trouver que des correspondances de 4 octets exactement (à l'exception de choses comme 1.1.1.1.1), utilisez ceci:

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

Il ne devrait jamais détecter d’adresses non-IP. L'expression pourrait être plus complexe pour vérifier plus de choses, mais cela devrait fonctionner dans la plupart des cas. Il ne correspondra pas à un 0 précédent car 010.1.12.1 n'est pas un moyen courant d'écrire des adresses IP.

Stefan Seidel
la source
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.
la source
3

Un peu délicat, mais ça devrait marcher:

( X='\([0-9]\{1,2\}\|1[0-9]\{2\}\|2[0-4][0-9]\|25[0-5]\)' ; grep "\([^\.]\|^\)$X\.$X\.$X\.$X\([^\.]\|$\)" file )
cYrus
la source
Et 127.000.000.001alors? ;-)
Arjan
Pour autant que je sache, les IP n'ont pas de zéros de remplissage.
cYrus
1
Hmmm, ping 127.000.000.001ça marche sûrement sur mon Mac. Mais alors: je viens d’apprendre que cela ping 2130706433donne même le même résultat. :-) Oups, ping 00127.00000.00000.00001traduit en 87.0.0.1. Bizarre ... ou octal peut-être? Oui, octal bien sûr, alors vous avez raison de deviner des zéros, je suppose.
Arjan
Oui, 00127 (octal) = 87 (décimal). Ce sont sûrement toutes des adresses IP valides, mais je suppose que ce n'est pas la manière standard de les représenter. Quoi qu'il en soit, ce n'est pas demandé par le demandeur.
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]) $ '

Version modifiée de la réponse d'Arnaud B.

Cette expression ne fera pas correspondre les adresses IP avec les 0 premiers. Par exemple, elle ne correspondra pas à 192.168.1.01 Cette expression ne correspondra pas aux adresses IP de plus de 4 octets. par exemple, il ne correspondra pas à 192.168.1.2.3

Thomas
la source
Cela ne correspondra pas non plus à 127.0.0.1.
Chris Charabaruk
0

J'utilise egrep "^([0-9]{1,3}\.){3}[0-9]{1,3}" /etc/hosts pour faire correspondre les adresses IP au début d'une ligne. Il peut également être utilisé sans ^pour autoriser les espaces ou autres caractères avant l'adresse 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
la source
0

Une version plus courte de la longue expression régulière:

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

Veuillez utiliser grep -E ou egrep en fonction de la version de votre système d'exploitation.

Suhail
la source
2
Bienvenue au super-utilisateur. Cette question a déjà plusieurs bonnes réponses. Pour aider les gens à comprendre les différences qui les séparent, modifiez votre réponse et expliquez ce qui la rend meilleure / différente des autres.
Máté Juhász
cette expression ne prend pas en compte ces ips juridiques tels que 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}'=> pas de résultat
anneb le
0

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

Exemple: curl http://korben.info/ip | grep "IP visible depuis mon serveur" | grep -Eo '([0-9] {1,3}.?) {4}'

utilisateur2357585
la source
0

Expression régulière pour faire correspondre une adresse IP dans TCL

définir 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"
}
abhilash.malla
la source
-1

Voici ce qui a fonctionné pour moi pour ksh et ksh93 sous 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 Ce qui précède peut être modifié afin de "filtrer" l’adresse IP fournie selon le modèle souhaité.

Niko
la source