【问题标题】:Python Parsing csv file containing ip and portsPython解析包含ip和端口的csv文件
【发布时间】:2017-08-09 06:57:07
【问题描述】:

我正在做一个解析 csv 文件的小项目

所以我正在处理的 csv 文件应该包含 IP,其打开的端口用逗号分隔

192.168.10.45,80,443,20,21,8080

192.168.10.49,22,80,21

所以,我正在尝试读取此文件,然后为每个端口编写一个输出文件,其中包含打开该端口的 ip 的 IP 地址。例如 22.txt 应该包含

192.168.10.45 192.168.10.49

任何想法我可以做到这一点或一个很好的参考。我还是python3的菜鸟

import csv
import sys

with open(sys.argv[1], 'rt') as f:
reader = csv.reader(f)
for row in reader:
    print((row)[1])

提前致谢!

【问题讨论】:

  • 文件是否仅包含 IP 地址和端口列表?

标签: python python-2.7 python-3.x csv network-programming


【解决方案1】:

我没有使用 csv 库,因为您的 csv 没有标头并且具有可变数量的开放端口。它更容易,代码/部门更少。这边。

不带 csv 包的版本 1

import os, sys
from collections import defaultdict

def main(csv):

    # use defaultdict so there is no need to initialize
    # use set to remove duplicate entries
    port_ip_map = defaultdict(set)

    # open with, handles errors open closing file handles etc.
    with open(csv, 'r') as f:
        # read lines
        lines = f.readlines()
        for line in lines:
            # ip must always be the first entry
            # port lists can have a variable length
            ip, *ports = line.split(',')
            for port in ports:
                # save ips by port
                port = int(port.strip())
                port_ip_map[port].add(ip)



    for port, ips in port_ip_map.items():
        line = ' '.join(ips)
        with open('{}.txt'.format(port), 'w') as f:
            f.write(line)




if __name__ == '__main__':
    # main(sys.argv[1])  # pass csv file by cli
    main('./test1.csv')

带有 csv 包的版本 2

import os, sys, csv
from collections import defaultdict

def main(csv_path):

    # use defaultdict so there is no need to initialize
    # use set to remove duplicate entries
    port_ip_map = defaultdict(set)

    # open with, handles errors open closing file handles etc.
    with open(csv_path, 'r') as f:
        # read lines
        reader = csv.reader(f)
        for row in reader:

            # ip must always be the first entry
            # port lists can have a variable length
            ip, *ports = row
            for port in ports:
                # save ips by port
                port = int(port.strip())
                port_ip_map[port].add(ip)



    for port, ips in port_ip_map.items():
        line = ' '.join(ips)
        with open('{}.txt'.format(port), 'w') as f:
            f.write(line)




if __name__ == '__main__':
    # main(sys.argv[1])  # pass csv file by cli
    main('./test1.csv')

样本输入:test1.csv

192.168.10.49,22,80,21
192.168.10.45,80,443,20,21,8080

样本输出:

defaultdict(<class 'set'>, {22: {'192.168.10.49'}, 80: {'192.168.10.45', '192.168.10.49'}, 21: {'192.168.10.45', '192.168.10.49'}, 443: {'192.168.10.45'}, 20: {'192.168.10.45'}, 8080: {'192.168.10.45'}})

【讨论】:

  • 可以,不过没必要,忘了加上写port.txt文件。稍后添加它
  • 是的。现在您正在滚动自己的 csv 拆分。
  • 使用 csv 包添加的版本。仍然认为这是矫枉过正,但不是我决定的立场;)
  • 感谢@mumbala 的帮助。第二个版本完成了这项工作。
【解决方案2】:

假设您要查找的端口是您可以执行的脚本的第二个参数:

import csv
import sys

infile = sys.argv[1]
port = sys.argv[2]

with open(infile, 'rt') as f:
    reader = csv.reader(f)
    for row in reader:
        if port in row[1:]:
            print('{}:{}'.format(row[0], port))

在这里,对于文件中的每一行,if port in row[1:] 行将在列表的每个元素中查找端口。我想这就是你想要的?

请注意,我已经稍微修改了print 行以打印端口。

【讨论】:

    【解决方案3】:

    您应该考虑使用 Python 字典或 dict。收藏库中还有一个 OrderedDict。

    例如:

        import collections
    
        ips_ordered_by_port = collections.OrderedDict()
        with open(sys.argv[1], 'rt') as f:
        reader = csv.reader(f)
        for row in reader:
            row_parts = row.split(',')
            ip = row_parts[0]
            for row_part_idx in range(1, len(row_parts)):
                port = row_parts[row_part_idx]
                ip_ordered_by_port = ips_ordered_by_port.get(port)
                if ip_ordered_by_port is None:
                    ips_ordered_by_port[port] = ip
                else:
                    ip_ordered_by_port.update(ip)
    

    现在您将拥有一个按端口(键)排序的字典,并且对于每个键,项目(值)将是 IP 地址。要遍历每个密钥,请为该密钥创建一个文件并写下我留给您的所有 IP 地址。

    当然,上面的代码可以重构为几个函数,以获得更好的可读性和可测试性。

    【讨论】:

    • 非常感谢@ozOil 的帮助。将尝试在 python 中变得更好并自己完成工作。
    【解决方案4】:

    我喜欢使用 ipaddress 模块,并将其放回另一个 csv。在使用防火墙或负载平衡器配置时非常有用。将其放回 csv 文件可以让您在桌面上重新格式化它以使其成为 excel,然后根据端口号创建表格。

    import ipaddress
    import csv
    
    list1 = []
    list2 = []
    
    with open(file, "r") as csvfile:
        csvreader = csv.reader(csvfile, delimiter="'", dialect="excel")
        for i in csvreader:
            try:
                if ipaddress.IPv4Address(i[1]).version == 4:
                    list1.append(i[1])
                elif int(i[2]) == True:
                    list2.append(i[2])          
                except ipaddress.AddressValueError:
                    pass
                except IndexError:
                    pass
    
    rows = zip(list1, list2)
    
    with open(file + "_final.csv", "w") as finalcsv:
        writer = csv.writer(finalcsv, dialect="excel")
        for i in rows:
            writer.writerow(i) 
    

    【讨论】:

      【解决方案5】:

      如何计算 CSV 列中的重复 IP。示例(192.168.0.1 3 次)

      192.168.0.1 198.168.1.101 192.168.0.1 192.168.0.1

      【讨论】:

      • 你在问吗?
      猜你喜欢
      • 2017-09-02
      • 2013-04-16
      • 2017-03-09
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      • 2017-05-14
      • 2010-12-14
      • 1970-01-01
      相关资源
      最近更新 更多