Найти текст с подстановочным знаком

Протестировано в 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

1
18.10.2019, 22:27
2 ответа
Записи

/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)и переходит к следующая строка ввода.

2
27.01.2020, 23:22

Вообще-то, судя по вашим комментариям, это не настоящий файл hosts, а просто список доменных имён, так что вас вроде устраивает фильтрация всех строк хотя бы по двум точкам:

grep '\..*\.' hostfile

Если важно, чтобы домен находился в начале строки, используйте

grep '^[[:alnum:]]*\..*\.' hostfile
1
27.01.2020, 23:22

Теги

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