2014-09-29 2 views
1

У меня есть текстовый файл, содержащий длинный список отсортированных IP-адресов. Образец файла выглядит следующим образом:Сценарий оболочки для проверки и ввода IP-адресов

103.21.244.0/22  1; #Cloudflare 
103.22.200.0/22  1; #Cloudflare 
103.31.4.0/22  1; #Cloudflare 
104.16.0.0/12  1; #Cloudflare 
108.162.192.0/18 1; #Cloudflare 
141.101.64.0/18  1; #Cloudflare 
162.158.0.0/15  1; #Cloudflare 
173.245.48.0/20  1; #Cloudflare 
188.114.96.0/20  1; #Cloudflare 
190.93.240.0/20  1; #Cloudflare 
197.234.240.0/22 1; #Cloudflare 
198.41.128.0/17  1; #Cloudflare 
199.27.128.0/21  1; #Cloudflare 

Я пытаюсь написать скрипт, который выполняет следующие действия:

  1. Для данного IP-адреса (например, 1.2.3.4) или диапазон IP (например, 1.2.3.0/24), выясните, находится ли он в файле.

  2. Если это так, ничего не делайте. Если это не так, вставьте его в файл в нужном месте.

Проблемы:

A. Я застрял на проверку ли IP-адрес или диапазон IP уже в файле, так как простой Grep не будет делать. Например, grep вернет отрицательный результат для IP 188.114.98.200, который на самом деле уже представлен 188.114.96.0/20. Аналогично для 188.114.98.0/24.

B. Я также не знаю, как вставить IP-адрес/диапазон в нужном месте, не нарушая порядок сортировки.

Может кто-нибудь помочь? Большое спасибо.

Edit:

Хорошо, посмотрев на предложения, я предполагаю, что я не должен без необходимости ограничивать себя Bash, особенно, если есть уже существующие библиотеки на других языках, которые могут получить работу без труда.

+1

Что касается вставки в нужное место, я бы просто добавить к концу, а затем обратиться к файлу. не так уверен в совпадении '..98.200' с' ..96.0/20'. Удачи. – shellter

+1

Просьба пояснить логику, с помощью которой вы определяете, как '188.114.98.200' равно' 188.114.96.0/20' или '188.114.98.0/24'. –

+0

@AbhishekPathak предположительно через какую-то логику сетевой маски: http://en.m.wikipedia.org/wiki/Classless_Inter-Domain_Routing – deau

ответ

1

Мне кажется, что сравнение/соответствие строк в формате IP будет довольно раздражающим.

Это page (листинг 4) имеет хороший и простой трюк, чтобы преобразовать строку IP в массив целых чисел, используя только подстановку параметров Баша (документированный here, искать ${var#Pattern}, ${var##Pattern}).

Если вы хотите поймать маску, добавьте что-то вроде IP[5]=${tmp##*/} (с обозначениями linux mag pdf).

Для простого сопоставления IP вы можете просто сравнить/сопоставить массивы целых чисел с арифметической оценкой bash ((...)) (например, зарегистрировано here).

Для более сложного соответствия CIDR вы либо сами реализуете довольно немного логики, либо можете попробовать такие инструменты, как ipcalc (check this), который доступен на большинстве дистрибутивов Linux.

+0

Спасибо. Но я могу пойти с предложением от @klashxx, если уже есть библиотека для сравнения и сопоставления IP-адресов, даже если это не Bash. – GooDoo

0

bash Не, но это задача довольно проста, используя Python:

>>> print ips 
103.21.244.0/22  1; #Cloudflare 
103.22.200.0/22  1; #Cloudflare 
103.31.4.0/22  1; #Cloudflare 
104.16.0.0/12  1; #Cloudflare 
108.162.192.0/18 1; #Cloudflare 
141.101.64.0/18  1; #Cloudflare 
162.158.0.0/15  1; #Cloudflare 
173.245.48.0/20  1; #Cloudflare 
188.114.96.0/20  1; #Cloudflare 
190.93.240.0/20  1; #Cloudflare 
197.234.240.0/22 1; #Cloudflare 
198.41.128.0/17  1; #Cloudflare 
199.27.128.0/21  1; #Cloudflare 

>>> import iptools 
>>> [raw_range for raw_range in ips.splitlines()      
... if '188.114.98.200' in iptools.IpRangeList(raw_range.split()[0])] 
['188.114.96.0/20  1; #Cloudflare']        
>>>                 
>>> [raw_range for raw_range in ips.splitlines()      
... if '188.112.98.200' in iptools.IpRangeList(raw_range.split()[0])] 
[] 
+0

Спасибо. Я не знаком с Python, но если он выполнит свою работу, я открыт для этого. В конце концов, Python уже установлен, и, похоже, сложно создать логику для сравнения/соответствия IP-адресов в Bash. Спасибо, что указали мне на библиотеку iptools. Пойдем, чтобы узнать больше об этом. – GooDoo

Смежные вопросы