首页 > 解决方案 > 用于将 IPv6 地址转换为数字(或字符串)的大型 CSV 文件脚本

问题描述

所以我有一个很大的 csv 文件,超过 1gb。在 ipv4 和 ipv6 中有一个 IP 地址列。我想将 ipv6 地址转换为数字,但是 libre calc 的行太多。所以我想知道是否可以在终端中使用python来转换所有的ipv6地址。

另外,我可以将文件分成更小的部分,然后使用 libre calc,但同样的问题——我也不知道如何编写脚本。

编辑:

我不介意,但它可能会变得更复杂。也不确定这应该如何格式化,但我希望人们能明白……所以我有一张带有 IPv6 地址的表,例如这些示例:

2001:db8::cafe:1111
2001:db8:0:a:1:2:3:4
2001:db8:aaaa::c
2001:db8:0:0:1::4

有很多不同的规则来管理格式——对我来说太难了。我听说python有一个专门返回转换的函数,但不确定其余的(如何正确地将返回的值返回到csv中,格式不中断等)。无论如何,这是另一张表中的一行:

"58569107296622255421594597096899477504","58569107375850417935858934690443427839","NG","Nigeria","Abuja Federal Capital Territory","Abuja","9.057350","7.489760"

所以我需要匹配的部分是前两个数字(前两列),其中有几个范围

"0","340282366920938463463374607431768211455"

所以我想获取 IPv6 地址,将它们转换为 IP 号码,然后将它们分类到各自的范围内。

标签: shellscriptingpythoncsvipv6

解决方案


是的,这是你可以在 Python 中做的事情。我将通过一些简短的片段和指向文档的链接进行演示,这些文档将无法提供完整的解决方案,从而为您提供自己将各个部分组合在一起所需的资源。

首先,如果你想逐行加载一个 CSV 文件并写入第二个文件,你会这样做:

>>> import csv
>>> with open('eggs.csv', newline='') as in and open('omellette.csv', 'w') as out:
...     r = csv.reader(in)
...     w = csv.writer(out)
...     for row in r:
...         print(', '.join(row)) # print unmodified
...         row[0] = ipToNum(row[0])
...         row[1] = ipToNum(row[1])
...         print(', '.join(row)) # print modified
...         w.writerow(row)
Spam, Spam, Spam, Spam, Spam, Baked Beans
Spam, Lovely Spam, Wonderful Spam

可以在此处找到此示例所基于的原始文件以及有关 python 内置 CSV 功能的其他信息:

您可能需要根据特定 CSV 文件的确切格式进行调整。现在,要将 IP 地址转换为数字,您可以执行以下操作:

import socket, struct

def ipToNum(ip):
    "convert ipv4/6 string to long integer"
    return struct.unpack('>L',socket.inet_pton(ip))[0]

def numToDottedip(n):
    "convert long int to ipv4/6"
    return socket.inet_ntop(struct.pack('>L',n))

这个例子改编自我在这里找到的:

你将不得不修改它

此外,如果您想了解更多关于 socket 和 struct 模块的信息,请参阅文档:

您不需要拆分文件,因为 CSVreader对象一次只会返回一行,而不是一次读取整个文件。当然,一旦你读了这些数字,你可能也想对它们做一些实际的事情,但由于你没有指定,我会告诉你的。

另请注意,我没有尝试过任何此代码。值得在这里以比喻的形式重复一遍:我试图教你钓鱼,而不仅仅是给你鱼。接受这个建议并努力让它自己工作符合你的最大利益,因为这将是你真正成为一名程序员的第一步。


推荐阅读