J'ai une phrase qui contient une adresse IP. Par exemple,
This sentence contains an ip number 1.2.3.4 and port number 50, i want to print the IP address only.
De la phrase ci-dessus, je veux imprimer l'adresse IP uniquement. Comment puis-je faire ceci? J'ai entendu dire qu'il est possible de faire cela avec sed
C'est possible, mais pas élégant:
echo 'This sentence contains an ip number 1.2.3.4 and port number 50, i want to print the IP address only.' \
| sed 's/.*\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*/\1/'
[0-9]
correspond à n'importe quel chiffre, \{1,3\}
signifie qu'il peut être répété 1 à 3 fois. \.
correspond à un point. L’ensemble de l’IP est capturé par les parenthèses \(...\)
, ce qui vient avant et après est associé à .*
, c’est-à-dire tout ce qui est répété au moins zéro fois. La chaîne de correspondance complète (c'est-à-dire la ligne entière) est ensuite remplacée par le contenu du premier groupe de correspondance.
Vous pouvez le rendre plus lisible en introduisant une variable:
n='[0-9]\{1,3\}'
... | sed "s/.*\($n\.$n\.$n\.$n\).*/\1/"
Il imprime la chaîne entière si l’adresse IP n’est pas trouvée. Il ne vérifie pas non plus les adresses IP non valides telles que 256.512.999.666.
Ceci est une solution grep
:
echo "$sentence" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'
-o
n'imprime que la partie correspondante-E
passe au regex étendu[0-9]
) une ou plusieurs fois (+
), puis à un point (\.
) et à nouveau ...Voici une autre solution avec Perl
:
echo "$sentence" | Perl -l -ne '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ && print $&'
-l
a spécifié le terminateur de ligne (nouvelle ligne)-n
boucle dans l'entrée donnée par echo
(peut être plusieurs lignes)-e
le code suitgrep
ci-dessusUtilisez cette commande de grep
:
grep -Eo '[0-9.]+ ' file
Ou même mieux:
grep -oP '\d+\.\d+\.\d+\.\d+' file
ou
grep -Eo "([0-9]{1,3}[\.]){3}[0-9]{1,3}" file
J'utilise grep:
echo 'This sentence contains an ip number 1.2.3.4 and port number 50, i want to print the IP address only.' | grep -oE '((1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.){3}((1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]))'
Cela n’imprimera que les adresses IP valides, contrairement aux autres réponses.
Je ferais cela dans python 3 interprète. Il saisit non seulement le texte qui se trouve dans ce format 111.111.111.111
mais il vérifie également si le texte est valide ou non.
>>> import re
>>> import ipaddress
>>> text = "This sentence contains an ip number 1.2.3.4 and 111.111.111.111 451.976.897.786 port number 50, i want to print the IP address only."
>>> foo = re.findall(r'(?<!\S)(?:\d{1,3}\.){3}\d{1,3}(?!\S)', text)
>>> foo
['1.2.3.4', '111.111.111.111', '451.976.897.786']
>>> for i in foo:
... try:
... ipaddress.ip_address(i)
... except:
... pass
...
IPv4Address('1.2.3.4')
IPv4Address('111.111.111.111')
Pour obtenir l'interpréteur python 3, tapez la commande python3
sur le terminal.
Extension à la réponse de choroba:
Si vous ne voulez pas que la nouvelle ligne soit imprimée et que vous voulez uniquement imprimer les adresses IP:
$ echo -e 'This sentence contains an ip number 1.2.3.4 and port number 50, \ni want to print the IP address only.\n One more IP is 1.24.53.3.' \
| sed -n 's/.*\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*/\1/1p'
Sortie:
1.2.3.4
1.24.53.3
Explication:
-n flag is for quiet / silent.
p print the replaced text
AWK combiné avec RegExp est très approprié pour le traitement de parties de lignes.
L'idée de base du soufflet à une ligne est de traverser une ligne et de vérifier la présence de quatre chiffres et points, répétés 4 fois au maximum; en même temps, nous pouvons rechercher un chiffre répété 2 à 4 fois pour le numéro de port
awk '{for(i=1;i<=NF;i++) { if ($i~/[[:digit:]\.]{4}/) printf $i; if ( $i~/[[:digit:]]{2,4}/) printf ":"$i }}'
Échantillon échantillon
$ echo "This sentence contains an ip number 1.2.3.4 and port number 50, i want to print the IP address only." | awk '{for(i=1;i<=NF;i++) { if ($i~/[[:digit:]\.]{4}/) printf $i; if ( $i~/[[:digit:]]{2,4}/) printf ":"$i }}'
1.2.3.4:50,
Votre phrase contient 50 et, ensemble sans séparation, donc imprimées ensemble, mais avec gsub(/[[:punct:]]/,"")
pouvant être supprimées si vous le souhaitez.