Протестировано в SmartOS(варианте Solaris ), надеюсь, должно работать в других *средах nix:
egrep '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])'
Пример:
$ cat >file.txt
IP1: 192.168.1.1
IP2: 261.480.201.311
IP3: 1012.680.921.3411
$ egrep '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])' file.txt
IP1: 192.168.1.1
Этот шаблон соответствует только действительному IPv4, т. е. x.x.x.x
, где x
находится в диапазоне от 0 -255. Если вам нужно извлечь только совпадающий IP-адрес, добавьте параметр -o
в вышеуказанная команда. Вы можете встроить эту команду в сценарий bash и, предположительно, в другие сценарии оболочки. И, если egrep
терпит неудачу,try grep -E...
Использование в (сценарии оболочки bash ):
ip=$(egrep -o '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])' file.txt)
echo $ip
/etc/hosts
могут иметь одно или несколько имен хостов на IP-адрес, поэтому нам нужно проверить каждое имя хоста (, то есть все поля, кроме первого поля ), чтобы увидеть, содержит ли оно 2 или более .
символов.
Например:
awk '{for (f=2;f<=NF;f++) {if (split($f,array,/\./)>2) {print;last}}}' /etc/hosts
или, с добавлением перевода строки и отступа для улучшения читабельности:
awk '
{
for (f=2;f<=NF;f++) {
if (split($f,array,/\./) > 2) {
print;
last;
}
}
}' /etc/hosts
Будет напечатана каждая строка в /etc/hosts
, где любое из имен хостов содержит как минимум 2 символа .
.
Он перебирает каждое поле в строке ввода и использует для этого функцию awk split()
, разбивая на .
символов. Строка, разделенная на элементы разделителем, всегда будет иметь на 1 элемент больше, чем количество разделителей, поэтому проверка должна быть > 2
, а не >= 2
. например. «пример» будет иметь один элемент, сам по себе. «example.com» будет состоять из двух элементов («example» и «com» ). "mobile.example.com" будет иметь 3.
split()
также разбивает строку на массив, но для этой задачи нас интересует только возвращаемое значение (количество элементов )и игнорируем массив.
Как только скрипт находит одно имя хоста с двумя или более .
символами, он печатает всю строку, выходит из цикла for (с помощьюlast
)и переходит к следующая строка ввода.
Вообще-то, судя по вашим комментариям, это не настоящий файл hosts, а просто список доменных имён, так что вас вроде устраивает фильтрация всех строк хотя бы по двум точкам:
grep '\..*\.' hostfile
Если важно, чтобы домен находился в начале строки, используйте
grep '^[[:alnum:]]*\..*\.' hostfile