【问题标题】:Sort list of IP addresses with subnet mask, removing duplicates使用子网掩码对 IP 地址列表进行排序,删除重复项
【发布时间】:2012-11-30 23:13:42
【问题描述】:

我有一个包含这些 IP 地址的 txt 文件,我想对它们进行排序以删除重复的 IP 地址,但保留 /subnets。

4.4.4.4/32
4.2.2.2/32
4.4.4.4/32
4.2.2.2/32
4.2.2.2/28
4.4.4.4/24
2.2.2.2/32

例如:排序和去除重复后,上面变成了

4.4.4.4/32
4.2.2.2/32
4.2.2.2/28
4.4.4.4/24
2.2.2.2/32

任何使用 awk 或 perl 或 python 的技巧?我也想按升序排序。

【问题讨论】:

  • 为什么简单的sort -u 不够用?
  • 谢谢。 sort -u 很好,但我正在寻找一个 python/perl 脚本。应该清楚地表达我的问题..
  • 您的预期输出是什么?您的意思是消除重复 IP,不管 /32、/28、...?
  • 更新后的问题:正如您所说,您所需要的只是基本的词汇排序。你有什么问题?请向我们展示您的作品。
  • 发布的所需输出未按任何明显标准排序。你的排序标准是什么?

标签: python perl sorting ip-address


【解决方案1】:

在python中你可以这样做:

In [3]: l = []

In [4]: with open('ipaddress.txt', 'r') as input_file:
   ...:     for elem in input_file.readlines():
   ...:         if elem.strip() not in l:
   ...:             l.append(elem.strip())
   ...:

In [5]: l
Out[5]: ['4.4.4.4/32', '4.2.2.2/32', '4.2.2.2/28', '4.4.4.4/24', '2.2.2.2/32']

【讨论】:

【解决方案2】:

你应该可以使用sort -ur来做到这一点。

编辑:要在 python 中执行此操作,您可以执行以下操作:

with open('ipaddress.txt', 'r') as f:
    address = sorted(list(set(line for line in f)), reverse=True)
    for ad in address:
        print(ad)

【讨论】:

  • +1 用于命令行解决方案,如 'sort -ur ipaddress.txt >ipaddress_uniq.txt'
【解决方案3】:

您可以使用 awk 按照它们在文件中出现的顺序获取唯一的行:

awk '!seen[$0]++'

如果你想要整个管道:

awk '/#/{sub(/#.*/,"",$0)} length($0) && !seen[$0]++' ipnum.txt

未测试

【讨论】:

    【解决方案4】:

    由于数据看起来非常规则,因此在 Python 中使用 key 参数很容易确保正确排序。这用于为要排序的列表中的每个实例创建一个“排序键”。人们经常使用 lambda 作为排序键函数,但为了完整起见,我们将定义一些有用的东西。

    重复删除最好在 Python 中的排序之前完成。由于无论如何都必须对列表进行排序,因此将其转换为集合将导致唯一字符串的任意排序无关紧要,如果排序没有,则“唯一化”列表 l 的简单方法'在 Python 中无关紧要

    l = list(set(l))
    

    顺便说一句,您的测试数据选择不当,因为它会在词法排序上正确排序(只是偶然)。因此,您最好在地址中包含一些具有两位数和三位数组件的示例,这样就不再正确了。我通过解释的方式演示了非工作排序。

    In [42]: data = """\
    4.4.4.4/32
    4.2.2.2/32
    4.4.4.4/32
    4.2.2.2/32
    4.2.2.2/28
    4.4.4.4/24
    2.2.2.2/32
    12.13.14.15/24
    11.12.13.14/24""".splitlines()
    
    In [43]: data.sort()
    
    In [44]: data
    Out[44]: 
    ['11.12.13.14/24',
     '12.13.14.15/24',
     '2.2.2.2/32',
     '4.2.2.2/28',
     '4.2.2.2/32',
     '4.2.2.2/32',
     '4.4.4.4/24',
     '4.4.4.4/32',
     '4.4.4.4/32']
    
    In [45]: data = list(set(data))
    
    In [46]: data.sort()
    
    In [47]: data
    Out[47]: 
    ['11.12.13.14/24',
     '12.13.14.15/24',
     '2.2.2.2/32',
     '4.2.2.2/28',
     '4.2.2.2/32',
     '4.4.4.4/24',
     '4.4.4.4/32']
    
    In [48]: def sortkey(addr):
       ....:     add, pref = addr.split("/")
       ....:     a, b, c, d = (int(x) for x in add.split("."))
       ....:     return a, b, c, d, int(pref)
       ....: 
    
    In [49]: data.sort(key=sortkey)
    
    In [50]: data
    Out[50]: 
    ['2.2.2.2/32',
     '4.2.2.2/28',
     '4.2.2.2/32',
     '4.4.4.4/24',
     '4.4.4.4/32',
     '11.12.13.14/24',
     '12.13.14.15/24']
    

    排序键函数在 Python 中并不重要,因为它作为“装饰/排序/取消装饰”算法的一部分仅应用于每个列表值一次。更一般地说,对于这个问题域,您可能会发现 ipaddress 模块很有帮助:http://docs.python.org/dev/howto/ipaddress.html

    【讨论】:

      猜你喜欢
      • 2021-12-30
      • 2013-12-03
      • 2015-10-18
      • 2011-09-09
      • 2013-11-12
      • 2020-01-10
      • 2013-01-16
      • 2022-08-19
      • 1970-01-01
      相关资源
      最近更新 更多