-3

我有一个包含这些 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 的任何提示?我也想按升序排序。

4

4 回答 4

3

您应该能够仅使用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)
于 2012-12-13T05:34:02.903 回答
2

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

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

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

于 2012-12-13T06:05:01.563 回答
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']
于 2012-12-13T05:32:22.993 回答
0

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

awk '!seen[$0]++'

如果你想要整个管道:

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

未经测试

于 2012-12-13T05:35:00.703 回答