如何使用 python3 对 csv 文件中的 ip 地址进行排序
How to sort ip addresses in csv file using python3
我有一个如下所示的 csv 文件:
IP Address,Port,Protocol,State
192.168.3.1,53,tcp,open
192.168.13.100,80,tcp,open
192.168.3.1,443,tcp,close
192.168.3.71,1080,tcp,open
192.168.3.7,8888,tcp,open
192.168.23.12,80,tcp,filtered
192.168.3.12,443,tcp,open
192.168.3.12,631,tcp,open
如何在 python 3 中先按 IP 地址排序,然后按端口号排序?
我试过用这个:
#!/bin/python3
# import modules
import csv, ipaddress
data = csv.reader(open('list.csv'),delimiter=',')
data = sorted(data, key = ipaddress.IPv4Address)
print('After sorting:')
print(data)
但是我得到了一个ipaddress.AddressValueError: Only decimal digits permitted in "['192" in "['192.168.3.1', '53', 'tcp', 'open']"
在按 IP 地址排序后,代码接下来应该检查端口,因为有可能 IP 地址相同但端口不同。
一个多星期以来,我一直在努力解决这个问题。谢谢
第一个问题是来自您的 csv reader 的数据包括 header 行。要跳过第一行,只需使用 reader 中的一行,然后再执行其他操作。
data = csv.reader(open('list.csv'),delimiter=',')
next(data) # Consumes the header line
data = sorted(...)
旁注:使用 with
以便在退出 with
块时自动关闭文件。
with open('list.csv') as file:
data = csv.reader(file)
next(data)
data = sorted(...)
现在,key
参数采用 函数 并传递 您正在排序的可迭代对象的每个元素 功能。现在你的 data
是一个迭代器,其中每个元素都是一个 list 代表 csv 文件的每一行。您不想为每一行传递整个列表,您只想传递所述列表的第一个元素。您可以使用 lambda expression 作为获取每个列表的键,并仅将第一个元素传递给 ipaddress.IPv4Address
.
data = sorted(data, key = lambda row: ipaddress.IPv4Address(row[0]))
因为你还想按端口排序,你可以让你的 lambda return 一个包含 IP 地址和端口号的元组。
data = sorted(data, key = lambda row: (ipaddress.IPv4Address(row[0]), row[1]))
如果您将 data
中的第一列转换为 IPv4Address
objects,您可能会发现它很有用,这样您就可以在别处使用它们。在这种情况下,请阅读您的 csv 文件 line-by-line 并在排序之前执行此操作。
with open('list.csv') as file:
reader = csv.reader(file)
next(reader)
data = []
for row in reader:
row[0] = ipaddress.IPv4Address(row[0])
data.append(row)
data.sort()
在这里,你不需要使用lambda函数,因为列表比较会自动比较第一个元素,然后是第二个元素,依此类推,并且行的元素已经是比较正确的类型。
我有一个如下所示的 csv 文件:
IP Address,Port,Protocol,State
192.168.3.1,53,tcp,open
192.168.13.100,80,tcp,open
192.168.3.1,443,tcp,close
192.168.3.71,1080,tcp,open
192.168.3.7,8888,tcp,open
192.168.23.12,80,tcp,filtered
192.168.3.12,443,tcp,open
192.168.3.12,631,tcp,open
如何在 python 3 中先按 IP 地址排序,然后按端口号排序?
我试过用这个:
#!/bin/python3
# import modules
import csv, ipaddress
data = csv.reader(open('list.csv'),delimiter=',')
data = sorted(data, key = ipaddress.IPv4Address)
print('After sorting:')
print(data)
但是我得到了一个ipaddress.AddressValueError: Only decimal digits permitted in "['192" in "['192.168.3.1', '53', 'tcp', 'open']"
在按 IP 地址排序后,代码接下来应该检查端口,因为有可能 IP 地址相同但端口不同。
一个多星期以来,我一直在努力解决这个问题。谢谢
第一个问题是来自您的 csv reader 的数据包括 header 行。要跳过第一行,只需使用 reader 中的一行,然后再执行其他操作。
data = csv.reader(open('list.csv'),delimiter=',')
next(data) # Consumes the header line
data = sorted(...)
旁注:使用 with
以便在退出 with
块时自动关闭文件。
with open('list.csv') as file:
data = csv.reader(file)
next(data)
data = sorted(...)
现在,key
参数采用 函数 并传递 您正在排序的可迭代对象的每个元素 功能。现在你的 data
是一个迭代器,其中每个元素都是一个 list 代表 csv 文件的每一行。您不想为每一行传递整个列表,您只想传递所述列表的第一个元素。您可以使用 lambda expression 作为获取每个列表的键,并仅将第一个元素传递给 ipaddress.IPv4Address
.
data = sorted(data, key = lambda row: ipaddress.IPv4Address(row[0]))
因为你还想按端口排序,你可以让你的 lambda return 一个包含 IP 地址和端口号的元组。
data = sorted(data, key = lambda row: (ipaddress.IPv4Address(row[0]), row[1]))
如果您将 data
中的第一列转换为 IPv4Address
objects,您可能会发现它很有用,这样您就可以在别处使用它们。在这种情况下,请阅读您的 csv 文件 line-by-line 并在排序之前执行此操作。
with open('list.csv') as file:
reader = csv.reader(file)
next(reader)
data = []
for row in reader:
row[0] = ipaddress.IPv4Address(row[0])
data.append(row)
data.sort()
在这里,你不需要使用lambda函数,因为列表比较会自动比较第一个元素,然后是第二个元素,依此类推,并且行的元素已经是比较正确的类型。