我有一个带有这些IP地址的txt文件,并希望对它们进行排序,删除重复的IP地址,但保留/子网。
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的任何提示?我还想按升序排序。
答案 0 :(得分: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 :(得分:2)
由于数据看起来非常规则,因此使用 key 参数确保在Python中正确排序是相当容易的。这用于为要排序的列表中的每个实例创建“排序键”。人们经常使用lambda作为排序键函数,但为了完整性,我们将 def 一些有用的东西。
在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
答案 2 :(得分:1)
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']
答案 3 :(得分:0)
您可以使用awk:
按照它们在文件中出现的顺序获取唯一的行awk '!seen[$0]++'
如果你想要整个管道:
awk '/#/{sub(/#.*/,"",$0)} length($0) && !seen[$0]++' ipnum.txt
<子>未测试子>