web-dev-qa-db-fra.com

Comment sélectionner et imprimer une adresse IP à partir d'un ensemble de chaînes?

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

3
Anandu M Das

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.

7
choroba

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
  • le motif correspond à chaque chiffre ([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 suit
  • la regex à l'intérieur du code Perl est très semblable à celle de la solution grep ci-dessus
6
chaos

Utilisez 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
2
αғsнιη

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.

1
Jiří Gracík

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.

0
Avinash Raj

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
0
snoop

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.

0