Python 将 CSV 中多行的数据合并(串联)到另一个 CSV 中的一个单元格中

Python combine (Concatenate) data from multiple rows in CSV into one cell in another CSV

我每天 运行 一些 nmap 扫描报告,我正尝试使用 Python 完全自动化。我有一个带有 IP 和端口号的 CSV,每行一个。我正在尝试将端口号合并为一个列表。以下是输入 csv 的示例:

    address       port
    192.168.3.5   80
    192.168.3.5   443
    192.168.3.5   3389
    192.168.3.5   137
    192.168.4.77  80
    192.168.4.77  445

输出应如下所示:

    address         ports
    192.168.3.5     80, 443, 3389, 137
    192.168.4.77    80,445

这是完整的脚本:

import subprocess

# Function to run peepingtom
def run_peepingtom(dir):

    scanfile = dir + '/nmap-scan.xml'

    subprocess.call(["python", "peepingtom/peepingtom.py", "-x", scanfile, "-o", dir + "/peepcaptures/"])


# Function to run NMAP on a list of IPs. The scan results will be in "dir" location
def run_nmap(dir):

    targets = dir + '/targets.txt'

    subprocess.call(["nmap", "-vv", "-A", "-sV", "-Pn", "-T4", "-iL", targets, "-oA", dir + "/nmap-scan"])

    # Create an HTML report
    subprocess.call(["xsltproc", dir + "/nmap-scan.xml", "-o", dir + "/nmap-scan.html"])


# Function to convert NMAP output to CSV
def run_nmap_parser(dir):

    scanfile = dir + '/nmap-scan.xml'

    subprocess.call(["python", "nmap-parser-xml-to-csv/nmap-parser-xml-to-csv.py", scanfile, "-s", ",", "-o", dir + "/nmap-scan.csv"])


def main():

    outputdir= '2015-07-20'

    run_nmap(outputdir)

    run_peepingtom(outputdir)

    run_nmap_parser(outputdir)


if __name__ == '__main__':
    main()

我写了一个 Python 脚本来进行扫描并创建 CSV 输出等。我使用了很少的开源工具来获得我需要的东西。之后我需要做更多的手动格式化,这就是我想要自动化的。我在 Python 方面的技能非常有限,因此非常感谢您的帮助,从哪里开始?

以下脚本将能够处理您输入的 CSV 文件。它读取 CSV 报告登录的每一行,并将每个 IP 地址添加到字典中。每个字典条目都包含 set 个用于给定 IP 地址的端口。输出按 IP 地址排序。

import csv, collections, socket

d_ip = collections.defaultdict(set)

with open("report_log.csv", "r") as f_input:
    csv_input = csv.reader(f_input, skipinitialspace=True)
    headers = next(csv_input)

    for row in csv_input:
        d_ip[row[0]].add(row[1])
        #d_ip[row[0]].append(row[1])   # if a list is preferred

with open("port_usage.csv", "wb") as f_output:
    csv_output = csv.writer(f_output)
    csv_output.writerow(headers)
    print "%-20s %s" % (headers[0], headers[1])

    # Sort by IP address
    ip_sorted = d_ip.keys()
    ip_sorted.sort(key=lambda x: socket.inet_aton(x))

    for ip in ip_sorted:
        l_ports = list(d_ip[ip])
        l_ports.sort(key=lambda x: int(x))
        csv_output.writerow([ip, ", ".join(l_ports)])
        print "%-20s %s" % (ip, ", ".join(l_ports))

这将打印以下输出:

address              port
192.168.3.5          80, 137, 443, 3389
192.168.4.77         80, 445

如果需要所有端口(不仅仅是唯一端口),只需更改为 defaultdict(list),将 .add() 更改为 .append() 并注释掉 sort