Как проверить, присутствует ли какой-либо IP-адрес в файле с помощью сценариев оболочки?

13

У меня есть скрипт, который генерирует какой-то вывод. Я хочу проверить этот вывод для любого IP-адреса, как

159.143.23.12
134.12.178.131
124.143.12.132

if (IPs are found in <file>)
then // bunch of actions //
else // bunch of actions //

Это fgrepхорошая идея?

У меня есть Bash доступны.

Кошур
источник
используйте grep, egrep, awk или sed, как
хотите
Не могли бы вы помочь с синтаксисом, пожалуйста? Я имею в виду, как он ищет случайный IP. Как описать шаблон? Я бы искал любой IP-адрес, а не конкретный адрес.
Кошур
5
Это только адреса IPv4 в четырехзначном формате? Могут ли они быть написаны как 0010.0000.0000.0001? Может ли файл содержать вещи, которые выглядят как IP-адреса, такие как номера версий ( soft-1.2.1100.1.tar.gzсетевые спецификации (10.0.0.0/24), 1.2.3.4.5)? Вы бы согласились с положительным решением 333.444.555.666? Или 0377.0377.0377.0377(действительный четырехзначный IP-адрес)?
Стефан Шазелас
Если bashдоступно, то awkобычно также, так что это может сработать для вас: awk '/([0-9]{2,3}\.){3}/ {print $5 "\t" $1}'(Этот однострочный переводит /etc/hostsформат списка XFR хоста в формат.)
Марк Хадсон

Ответы:

25

Да, у вас есть много вариантов / инструментов для использования. Я только что попробовал, это работает:

ifconfig | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"

так что вы можете использовать grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"для извлечения IP-адресов из вашего вывода.

Иджаз Ахмад Хан
источник
Благодарю. Это работает. Можешь немного объяснить? Это регулярное выражение?
Кошур
Да, это регулярное выражение, используемое в bash с grep, вы просто ищете шаблон из трех цифр, разделенных точками. вы можете поиграть, изменив числа в {1,2} на 2 цифры подряд и т. д.
Иджаз Ахмад Хан
Можно также использовать, "\b([0-9]{1,3}\.){3}[0-9]{1,3}\/[0-9][0-9]?"чтобы найти CIDR (если они действительны)
vikas027
2

начиная мой ответ на основе этого ответа:

Да, у вас есть много вариантов / инструментов для использования. Я только что попробовал, это работает:

ifconfig | grep -oE "\ b ([0-9] {1,3}.) {3} [0-9] {1,3} \ b" a, поэтому вы можете использовать grep -oE "\ b ([0- 9] {1,3}.) {3} [0-9] {1,3} \ b "для извлечения IP-адресов из вашего вывода.

и преобразование ответа в полный IPv6 и т. д.:

fgrep -oE "\b([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}\b" -- file

если вы хотите сохранить / nnn, если он там есть:

fgrep -oE "\b([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}(/[0-9]{1,3}){0,1}\b" -- file

а также есть сокращенная версия IPv6, которая включает в себя '::'.

Дополнительные ответы по IPv6 вы можете посмотреть здесь: /programming/53497/regular-expression-that-matches-valid-ipv6-addresses

Брайан Риттер
источник
fgrepстарое имя для варианта, grepкоторый игнорирует сопоставление с образцом. Я бы порекомендовал вам использовать grep(или даже egrep) вместо этого, особенно если вы явно хотите сопоставить шаблон.
Ройма
2

Если ваш файл называется, например, ipsвы можете написать что-то вроде:

while read -r ip
    do
        if [[ $ip == "$1" ]]; then
            shift
            printf '%s\n' 'action to take if match found'
        else
            printf '%s\n' 'action to take if match not found'
        fi
    done < ips

Затем вы можете передать параметры, следуя сценарию

./myscript 159.143.23.12 134.12.178.131 124.143.12.132 124.143.12.132
Валентин Байрами
источник
1

Надеюсь, что он протестирован в 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

Ганапати
источник
Это хорошо работало в системе CentOS 6, grep 2.6.3
Дэвид Рамирес,
0

Если у вас есть список IP-адресов в файле, по одному на строку, grepуже есть удобная -fопция:

$ man fgrep | grep file= -A1
       -f FILE, --file=FILE
              Obtain patterns from FILE, one per line.  The empty file contains zero patterns, and therefore matches nothing.  (-f is specified by POSIX.)

Это может привести к нескольким ложным срабатываниям из-за строк, за которыми может следовать другой номер, чтобы сделать его другим IP. Вы можете с этим многое сделать, в зависимости от вашего случая, вы можете или не можете волноваться.

chutz
источник
0

Я думаю, что мой ответ на другой пост лучше подходит здесь. Благодаря этому посту и другим подобным, я придумал этот, который ищет правильный IP-формат, а затем избавляется от всех строк, содержащих 256 или выше. Замените IP на что-то недопустимое, чтобы вместо него ничего не выводилось:

echo '255.154.12.231' | grep -E '(([0-9]{1,3})\.){3}([0-9]{1,3}){1}' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]'

Первый grep, вероятно, был найден в этом посте, и он проверяет любые числа от 0 до 999 в формате XXXX

Второй grep удаляет строки с номерами 256-999, оставляя только действительные IP-адреса формата, поэтому я подумал

НО ... Как указал G-Man, я ошибся, предположив, что IP будет на отдельной линии. Тем не менее, всегда есть место или другой разделитель для поиска по обе стороны от IP. Пробелы / разделители могут быть удалены с помощью sed или другими средствами после определения IP. Я также добавил -o к первому grep:

echo ' 1234.5.5.4321 ' | grep -Eo ' (([0-9]{1,3})\.){3}([0-9]{1,3}){1} ' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]' | sed 's/ //'

echo ' 234.5.5.432 ' | grep -Eo ' (([0-9]{1,3})\.){3}([0-9]{1,3}){1} ' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]' | sed 's/ //'
echo ' 234.5.5.100 ' | grep -Eo ' (([0-9]{1,3})\.){3}([0-9]{1,3}){1} ' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]' | sed 's/ //'

Первое и второе не дадут никакого вывода, а третье - и пробелы будут удалены.

Eyez
источник
Предположим, у меня 500 адресов в диапазоне от 10.0.0.1 до 10.0.1.244. Ваш второй grepвыбрасывает эту строку из-за «500». (В вопросе никогда не говорилось, что IP-адрес (а) в файле, если таковой имеется, сам по себе будет в строке.) С другой стороны, он примет 1234.1.1.1 и 1.1.1.1234. Но, кроме этого, неплохо.
G-Man говорит: «Восстановите Монику»
-1

Перенаправить этот вывод на некоторые outputFile

Просто grepоно с рисунком как,

grep -sE "159.143.23.12|134.12.178.131|124.143.12.132" <outputFile>
Кейшов Борат
источник
4
Обратите внимание, что .это оператор регулярного выражения, и его нужно экранировать, чтобы его можно было трактовать буквально
Стефан Шазелас
1
Это не шаблоны, это литералы. Не очень полезный ответ, поскольку в ОП указано «любой IP».
Марк Хадсон
-1
ip -4  addr show eth1 |  grep -oP '(?<=inet\s)\d+(\.\d+){3}'
Смит Джейн
источник