【问题标题】:Writing to a CSV file?写入 CSV 文件?
【发布时间】:2020-03-12 18:16:44
【问题描述】:

我对 python 很陌生,但是我编写了这段代码来读取一个 csv 文件,ping 第一列中的 IP 地址列表,并使用 csv writer 函数将状态和 IP 地址输出到另一个 csv 文件。最终我希望能够只将状态写入新的 csv 文件,因为所有其他数据都不会改变。谁能帮我做到这一点?本质上,我需要一种仅写入 TEST2.csv 中特定列的方法

import platform    # For getting the operating system name
import subprocess as sp  # For executing a shell command
import csv

def ping(host):
    """
    Returns True if host (str) responds to a ping request.
    Remember that a host may not respond to a ping (ICMP) request even if the host 
    name is valid.
    """

    # Option for the number of packets as a function of
    param = '-n' if platform.system().lower()=='windows' else '-c'

    # Building the command. Ex: "ping -c 1 google.com"
    command = ['ping', param, '2', host]

    return sp.call(command) == 0

with open('TEST.csv') as rfile:
    reader = csv.reader(rfile)
    count = 0 
    status = 0
    strstatus = ''
    with open('TEST2.csv','w',newline='') as wfile:
        fieldnames = ['a','b','c','d','IP Address', 'Status']
        # a,b,c,d are placeholders for other other fieldnames in datafile
        writer = csv.DictWriter(wfile,fieldnames=fieldnames)
        next(reader)
        writer.writeheader()
        for IP in reader:
            status = ping(IP)
            if status:
                strstatus = 'Online'
            else:
                strstatus = 'Offline'
            writer.writerow({'a':None, 'b':None, 'c':None , 'd':None , 'IP Address' : 
IP,'Status' : strstatus})
            count += 1
            if count > 4:
                break
rfile.close()
wfile.close()

【问题讨论】:

  • 不能只读取数据,修改元素,然后将结果写回文件吗?
  • 我遇到了一个文件在读写模式下都打开的问题。我明白你的意思,谢谢你的想法
  • 这很容易解决,不是吗?
  • 对 python 来说是全新的
  • 读取数据,保存/分配给某个变量,关闭文件,修改数据,写入输出。

标签: python file-handling


【解决方案1】:

使用您的一些代码完全重写,但应该可以完成这项工作:

import platform
import subprocess as sp
import csv

INPUT_FILENAME = 'Input.csv'
INPUT_FIELDNAMES = ['column_1', 'column_2', 'ip']
INPUT_DELIMITER = ';'

OUTPUT_FILENAME = 'Output.csv'
OUTPUT_DELIMITER = ';'
OUTPUT_FIELDNAMES = ['column_1', 'column_2', 'ip', 'status']

NUMBER_OF_PINGS = 2
pings = str(NUMBER_OF_PINGS)


def ping(host, pings=pings):
    # https://stackoverflow.com/a/32684938/3991125
    param = '-n' if platform.system().lower() == 'windows' else '-c'
    command = ['ping', param, pings, host]
    print('Pinging {}'.format(host))
    is_available = sp.call(command, stdout=sp.DEVNULL, stderr=sp.DEVNULL) == 0
    print('--> available: {}'.format(is_available))
    return is_available


def read_csv(filepath, fieldnames, delimiter):
    with open(filepath) as input_file:
        reader = csv.DictReader(input_file, fieldnames=fieldnames, delimiter=delimiter)
        data = [row for row in reader]
    return data


def work(data):
    for d in data:
        ip = d.get('ip')
        is_available = ping(ip)
        d['status'] = is_available
    return data


def write_csv(data, filepath, fieldnames, delimiter):
    with open(filepath, 'w') as output_file:
        writer = csv.DictWriter(output_file, fieldnames=fieldnames, delimiter=delimiter)
        writer.writeheader()
        writer.writerows(data)


if __name__ == "__main__":
    data = read_csv(INPUT_FILENAME, INPUT_FIELDNAMES, INPUT_DELIMITER)
    processed = work(data)
    write_csv(processed, OUTPUT_FILENAME, OUTPUT_FIELDNAMES, OUTPUT_DELIMITER)

【讨论】:

  • 为什么使用分号而不是逗号作为分隔符?
  • 我经常使用包含, 作为十进制符号的数据集。为防止出现任何并发症,我默认使用 ; 作为数据分隔符作为我的“个人最佳实践”/首选工作流程。
猜你喜欢
  • 2014-01-10
  • 1970-01-01
  • 2014-12-25
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-16
相关资源
最近更新 更多