用于检查和插入IP地址的Shell脚本

时间:2014-09-29 03:13:50

标签: bash shell

我有一个文本文件,其中包含一系列已排序的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

我正在尝试编写一个执行以下操作的shell脚本:

  1. 对于给定的IP地址(例如1.2.3.4)或IP范围(例如1.2.3.0/24),请确定它是否已存在于文件中。

  2. 如果是,请不要做任何事。如果不是,则将其插入到正确位置的文件中。

  3. 问题:

    一个。我一直在检查文件中是否已经存在IP地址或IP范围,因为简单的grep不会这样做。例如,grep将为IP 188.114.98.200返回否定值,实际上已经由188.114.96.0/20表示。同样适用于188.114.98.0/24

    B中。关于如何在正确的位置插入IP地址/范围条目而不弄乱排序顺序,我也很无能为力。

    有人可以帮忙吗?非常感谢你。

    修改

    好的,在查看了这些建议后,我想我不必将自己局限于Bash,特别是如果其他语言中已有的库可以轻松完成工作。

2 个答案:

答案 0 :(得分:1)

对我来说,比较/匹配IP格式字符串会非常烦人。

这个page(清单4)有一个很好的简单技巧,可以将IP字符串转换为整数数组,只使用bash参数替换(记录here,查找${var#Pattern}, ${var##Pattern} )。

如果你想抓住面具,可以添加IP[5]=${tmp##*/}之类的东西(附带linux mag pdf的符号)。

对于简单的IP比较,您可以简单地将整数数组与bash的算术评估((...))进行比较/匹配(例如,记录为here)。

对于更复杂的CIDR匹配,要么您愿意自己实现相当多的逻辑,要么尝试ipcalc(检查this)等大多数Linux发行版上都可用的工具。

答案 1 :(得分: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])]
[]