Как выбрать и распечатать IP-адрес из набора строк?

У меня есть предложение, которое содержит IP-адрес. Например,

This sentence contains an ip number 1.2.3.4 and port number 50, i want to print the IP address only.

Из приведенного выше предложения я хочу напечатать только IP-адрес. Как я могу это сделать? Я слышал, что это можно сделать с помощью sed

1
задан 21 November 2014 в 18:23

6 ответов

Это grep решение:

echo "$sentence" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'
-o печатать только совпадающую часть -E переключает в расширенное регулярное выражение, шаблон соответствует каждой цифре ([0-9]) один или несколько раз (+), затем точка (\.) и снова цифры ...

Здесь другое решение с perl:

echo "$sentence" | perl -l -ne '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ && print $&'
-o напечатайте только совпадающую часть -n с помощью ввода, заданного echo (может быть несколько строк) -E переключается на расширенное регулярное выражение регулярное выражение внутри Perl-кода очень так же, как в решении grep выше
6
ответ дан 24 May 2018 в 01:41
  • 1
    Греп кажется более комфортным. Спасибо, в любом случае – Anandu M Das 21 November 2014 в 18:26
  • 2
    @chaos не будет grep соответствовать любому символу для ., учитывая, что вы включили опцию -E? – skeggse 21 November 2014 в 19:28
  • 3
    @skeggse Ur, я изменил его, спасибо за вашу заметку – chaos 21 November 2014 в 19:33
  • 4
    @AvinashRaj Это вопрос совершенства. [0-9]{1,3} тоже будет соответствовать 987.567.432.999, и это не действительный IP-адрес. – chaos 21 November 2014 в 19:36
  • 5
    @chaos да, но по этой логике ваше регулярное выражение соответствует 298724387956458376345.1.1.1, что определенно не является действительным ip-адресом. – skeggse 21 November 2014 в 19:48

Используйте эту команду для grep:

grep -Eo '[0-9.]+ ' file

Или еще лучше:

grep -oP '\d+\.\d+\.\d+\.\d+' file

или

grep -Eo "([0-9]{1,3}[\.]){3}[0-9]{1,3}" file
2
ответ дан 24 May 2018 в 01:41

Я использую 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]))'

Это будет печатать только действительные IP-адреса, в отличие от других ответов

1
ответ дан 24 May 2018 в 01:41

Я бы сделал это в интерпретаторе python 3. Он не только захватывает текст, который находится в этом формате 111.111.111.111, но также проверяет правильность или нет.

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

Чтобы получить интерпретатор python 3, введите команду python3 на терминале. [ ! d1]

0
ответ дан 24 May 2018 в 01:41

Расширение для ответа choroba:

Если вы не хотите, чтобы новая строка была напечатана, и вы хотите только напечатать 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'

Выход:

1.2.3.4
1.24.53.3

Объяснение:

-n flag is for quiet / silent.
 p print the replaced text
0
ответ дан 24 May 2018 в 01:41

AWK, объединенный с RegExp, очень подходит для обработки частей линий.

Основная идея однострочного нижнего уровня состоит в том, чтобы прокрутить линию и проверить наличие четырех цифр и точек, повторяется максимум 4 раза; в то же время мы можем проверить цифру, повторяющуюся от 2 до 4 раз для номера порта

awk '{for(i=1;i<=NF;i++) { if ($i~/[[:digit:]\.]{4}/) printf $i; if ( $i~/[[:digit:]]{2,4}/) printf ":"$i  }}'

Пример прогона

$ 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,

Ваше предложение содержит 50 и вместе без разделения, поэтому напечатаны вместе, но с gsub(/[[:punct:]]/,""), которые могут быть удалены при желании.

0
ответ дан 24 May 2018 в 01:41

Другие вопросы по тегам:

Похожие вопросы: