У меня есть предложение, которое содержит 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
Это 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 выше Используйте эту команду для 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
Я использую 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-адреса, в отличие от других ответов
Я бы сделал это в интерпретаторе 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]
Расширение для ответа 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
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:]]/,""), которые могут быть удалены при желании.