【问题标题】:Csv file into seperate filesCSV 文件到单独的文件中
【发布时间】:2019-07-16 09:23:28
【问题描述】:

我需要根据列值将几个 csv 文件与传入和传出流量分开。此代码不提供任何输出或任何错误。

如果 source == ac:37:43:9b:92:24 && Receiver address == 8c:15:c7:3a:d0:1a 则需要将这些行写入 .out.csv 文件。

如果 Transmitter address == 8c:15:c7:3a:d0:1a && Destination== ac:37:43:9b:92:24 那么这些行需要写入 .in.csv 文件。

import csv
import os
import subprocess

startdir = '.'   
outdir = '.'
suffix = '.csv'

def decode_to_file(cmd, in_file, new_suffix):
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    filename = outdir + '/' + in_file[len(startdir):-len(suffix)] + new_suffix
    os.makedirs(os.path.dirname(filename), exist_ok=True)
    csv_writer = csv.writer(open(filename, 'w'))
    for line_bytes in proc.stdout:
        line_str = line_bytes.decode('utf-8')
        csv_writer.writerow(line_str.strip().split(','))

for root, dirs, files in os.walk(startdir):
    for name in files:
        if not name.endswith(suffix):
            continue
        in_file = os.path.join(root, name)

        decode_to_file(
            cmd= [source== "ac:37:43:9b:92:24" && Receiver address== "8c:15:c7:3a:d0:1a"],
            in_file=in_file,
            new_suffix='.out.csv'
        )
        decode_to_file(
            cmd= [Transmitter address == "8c:15:c7:3a:d0:1a" && Destination== "ac:37:43:9b:92:24"],
            in_file=in_file,
            new_suffix='.in.csv'
        )

【问题讨论】:

  • Subprocess.Popen 用于运行 bash 命令,而不是 python。而且您不能将 if 语句放在这样的列表中,它会在您定义它的行上执行一次。您可以定义一个小函数并将其作为cmd 传递,并且MAC 地址应该是一个字符串,用引号括起来。最后,在 Python 中,我们使用 lower_case_with_ubderscores 命名事物,所以 fileName 应该是 file_name 或者只是 filename。
  • @Boris 谢谢,我使用引号作为 MAC 地址并按照建议更改了文件名。但它仍然无法正常工作。我是编程新手,抱歉,我不确定如何定义函数并将其作为 cmd 传递。你能告诉我我该怎么做吗?谢谢
  • 用你的新代码更新你的问题。但它不起作用,因为您使用 subprocess.Popen 不正确。正确的方法是使用 csv 阅读器打开文件,遍历行并使用 if 语句过滤它们。
  • @Boris 我用你之前提到的更改更新了代码。请问如何进行其他更改?
  • 如果你想用python函数处理每个文件,使用multiprocessing模块并传递输入和输出文件路径。您还可以传递参数,指定用于确定将数据发送到哪个输出文件的列和值。

标签: python python-3.x csv python-3.7


【解决方案1】:
import csv
from pathlib import Path

startdir = Path(".")
outputdir = startdir / "filtered"


def write_csv(filename, rows, fieldnames):
    # if there's nothing to write, don't write anything
    if not rows:
        return

    filename.parent.mkdir(parents=True, exist_ok=True)
    with open(filename, "w") as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(rows)


for input_filename in startdir.glob("**/*.csv"):
    with open(input_filename) as input_csv:
        inrows = []
        outrows = []

        reader = csv.DictReader(input_csv)
        for row in reader:
            if (
                row["Source address"] == "ac:37:43:9b:92:24"
                and row["Receiver address"] == "8c:15:c7:3a:d0:1a"
            ):
                outrows.append(row)

            if (
                row["Transmitter address"] == "8c:15:c7:3a:d0:1a"
                and row["Destination address"] == "ac:37:43:9b:92:24"
            ):
                inrows.append(row)

        output_filename = outputdir / input_filename.relative_to(startdir)

        write_csv(output_filename.with_suffix(".out.csv"), outrows, reader.fieldnames)
        write_csv(output_filename.with_suffix(".in.csv"), inrows, reader.fieldnames)

【讨论】:

  • 谢谢我尝试了上面的代码,我没有收到任何错误但也没有输出。 fil.email/zj9vgFo3 我附上了一个示例 csv 文件。抱歉,我刚刚添加为图片
  • @Hasa 您的行被称为“目标地址”,而不是像您的屏幕截图/问题中的“目标”。我已经更新了代码。
  • 而且,代码应该已经抛出了KeyError。如果您没有看到任何错误,这可能意味着它没有找到任何 csv 文件。您所有的 csv 文件是否都以 .csv 结尾?您是从包含所有 csv 文件的目录中运行此脚本,还是将 startdir 更改为该目录的路径?如果将 csv 文件移动到与脚本相同的位置,它至少应该可以工作。
  • 非常感谢。有效。我可以只问一个问题吗?在这里,输出文件(.in.csv 和 out.csv)被写入与原始 csv 文件相同的位置。是否可以将所有输出文件(.in.csv 和 out.csv)保存到不同的位置/文件夹中,与原始文件具有相同的文件夹、子文件夹名称。非常感谢
  • 如果您对此感到满意,请给我一个 updoot 并标记为已接受。我为虚构的互联网点工作。
猜你喜欢
  • 2019-10-23
  • 2018-02-15
  • 2021-06-27
  • 2018-11-22
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 2018-03-15
  • 2015-05-04
相关资源
最近更新 更多