修复CSV文件';Python中的s格式

修复CSV文件';Python中的s格式,python,csv,Python,Csv,所以我打开了一个csv文件进行解析,但是csv中的某些行的格式不正确。csv格式通常如下所示: 'ipAddress','associatedTix''\n' 'ipAddress','associatedTix''\n' 'ipAddress','associatedTix''\n' 'ipAddress','associatedTix''\n' 'ipAddress','associatedTix''\n' 但在csv中的某些点(因为有多个associatedTix与ipaddress)当

所以我打开了一个csv文件进行解析,但是csv中的某些行的格式不正确。csv格式通常如下所示:

'ipAddress','associatedTix''\n'
'ipAddress','associatedTix''\n'
'ipAddress','associatedTix''\n'
'ipAddress','associatedTix''\n'
'ipAddress','associatedTix''\n'
但在csv中的某些点(因为有多个
associatedTix
ipaddress
)当有多个
associatedTix
时,其格式如下所示:

'ipAddress','associatedTix''\n'
'ipAddress','associatedTix''\n'
'ipAddress','associatedTix''\n'
'associatedTix','associatedTix''\n'
'associatedTix''\n'
'ipAddress','associatedTix''\n'
'ipAddress','associatedTix''\n'
因此,我要做的是以正确的格式获取csv:

for line in inputCsvFile:
    chunks = line.split(",")
        if associatedTix in chunks[0]:
            #go through the following line's after that line until you find an ip address
            #go one line above the line with the ip address
            #push that column to the above row, and repeat until you get to the original line3 row with the ip address

这3行注释是我在语法方面遇到的问题,因此,如果您能帮我确定语法,我们将不胜感激。此外,如果能确认我的逻辑将csv转换为正确的格式,我们将不胜感激

csv
正确处理带有换行符的字段,只要它们被引用:

$ cat t.csv
136.107.169.150,
165.246.197.229,"ESCCB ID#: 90Z-009204,
ESCCB ID#: 90Z-003262,
ESCCB ID#: 90Z-003011                   ESCCB ID#: 90Z-001047"
155.89.77.11,
91.195.188.160,
154.176.191.130,


所以你认为你有问题,其实你没有。您只需对第二个字段进行后期处理,然后将其写回。

csv
正确处理带有换行符的字段,只要它们被引用:

$ cat t.csv
136.107.169.150,
165.246.197.229,"ESCCB ID#: 90Z-009204,
ESCCB ID#: 90Z-003262,
ESCCB ID#: 90Z-003011                   ESCCB ID#: 90Z-001047"
155.89.77.11,
91.195.188.160,
154.176.191.130,


所以你认为你有问题,其实你没有。您所需要做的就是对第二个字段进行后期处理,然后将其写出来。

正如Ignacio所说,如果您使用的是
csv
模块,则实际上没有问题。如果您不想使用它,请使用以下选项:

with open("inCSV.txt", "r") as f:
    text = f.read()
    # Buffer
    b = ""
    keep_reading = False
    for line in text.split("\n"):
        if "\"" in line:
            # A bunch of tixs are going to appear!
            if b == "":
                # There are more tixs to read
                b += line
                # More tixs to come
                keep_reading = True
            else:
                # This is the last tix to read
                b += line.replace(",", "")
                # Remove newlines, extra whitespace and commas
                b = b.translate(None, " ,\n\"")
                # Add nice looking whitespace
                b = b.replace("E", " E")
                b = b.replace(":", ": ")
                b = b.replace("I", " I")
                b = b.strip()
                # Add comma after IP address
                ip_index = b.find(" ")
                b = b.replace(b[:ip_index + 1], b[:ip_index] + ",")
                # No more tixs to read
                keep_reading = False

                print b
                # reset buffer
                b = ""
        elif keep_reading:
            b += line
        else:
            print line
这样做的好处是,正如martineau所说,您不需要将整个文件存储在内存中

但是,如果使用
csv
模块,则必须进行更多操作:

import csv
with open("inCSV.txt", "r") as f:
    text = csv.reader(f)
    for line in text:
        # Get associated tix
        tix = line[1]
        # Remove newlines, extra whitespace and commas
        tix = tix.translate(None, " ,\n")
        # Add nice looking whitespace
        tix = tix.replace("E", " E")
        tix = tix.replace(":", ": ")
        tix = tix.strip()

        line[1] = tix
        print line
两者都将为您提供:

['248.53.88.234-24', '']
['61.15.168.199-24', '']
['181.140.27.200', '']
['192.128.254.150', '']
['8.160.137.156', 'ESCCB ID#: 90Z-007463']
['136.107.169.150', '']
['165.246.197.229', 'ESCCB ID#: 90Z-009204 ESCCB ID#: 90Z-003262 ESCCB ID#: 90Z-003011 ESCCB ID#: 90Z-001047']
['155.89.77.11', '']
['91.195.188.160', '']
['154.176.191.130', '']
['105.98.164.205', '']
['245.6.16.92', '']
['207.108.19.66', 'ESCCB ID#: 90Z-002345']
['84.71.75.211', 'ESCCB ID#: 90Z-008567 ESCCB ID#: 90Z-006765 ESCCB ID#: 90Z-009384ESCCB ID#: 90Z-001234ESCCB ID#: 90Z-007465']
['33.236.5.19', '']
['127.42.160.158', 'ESCCB ID#: 90Z-002939']
['94.34.104.184', '']

正如Ignacio所说,如果您使用的是
csv
模块,那么就没有什么问题了。如果您不想使用它,请使用以下选项:

with open("inCSV.txt", "r") as f:
    text = f.read()
    # Buffer
    b = ""
    keep_reading = False
    for line in text.split("\n"):
        if "\"" in line:
            # A bunch of tixs are going to appear!
            if b == "":
                # There are more tixs to read
                b += line
                # More tixs to come
                keep_reading = True
            else:
                # This is the last tix to read
                b += line.replace(",", "")
                # Remove newlines, extra whitespace and commas
                b = b.translate(None, " ,\n\"")
                # Add nice looking whitespace
                b = b.replace("E", " E")
                b = b.replace(":", ": ")
                b = b.replace("I", " I")
                b = b.strip()
                # Add comma after IP address
                ip_index = b.find(" ")
                b = b.replace(b[:ip_index + 1], b[:ip_index] + ",")
                # No more tixs to read
                keep_reading = False

                print b
                # reset buffer
                b = ""
        elif keep_reading:
            b += line
        else:
            print line
这样做的好处是,正如martineau所说,您不需要将整个文件存储在内存中

但是,如果使用
csv
模块,则必须进行更多操作:

import csv
with open("inCSV.txt", "r") as f:
    text = csv.reader(f)
    for line in text:
        # Get associated tix
        tix = line[1]
        # Remove newlines, extra whitespace and commas
        tix = tix.translate(None, " ,\n")
        # Add nice looking whitespace
        tix = tix.replace("E", " E")
        tix = tix.replace(":", ": ")
        tix = tix.strip()

        line[1] = tix
        print line
两者都将为您提供:

['248.53.88.234-24', '']
['61.15.168.199-24', '']
['181.140.27.200', '']
['192.128.254.150', '']
['8.160.137.156', 'ESCCB ID#: 90Z-007463']
['136.107.169.150', '']
['165.246.197.229', 'ESCCB ID#: 90Z-009204 ESCCB ID#: 90Z-003262 ESCCB ID#: 90Z-003011 ESCCB ID#: 90Z-001047']
['155.89.77.11', '']
['91.195.188.160', '']
['154.176.191.130', '']
['105.98.164.205', '']
['245.6.16.92', '']
['207.108.19.66', 'ESCCB ID#: 90Z-002345']
['84.71.75.211', 'ESCCB ID#: 90Z-008567 ESCCB ID#: 90Z-006765 ESCCB ID#: 90Z-009384ESCCB ID#: 90Z-001234ESCCB ID#: 90Z-007465']
['33.236.5.19', '']
['127.42.160.158', 'ESCCB ID#: 90Z-002939']
['94.34.104.184', '']

在您的示例中,有四个与ip关联的Tix?我怀疑您的文件是这样的。请把它的一部分复制粘贴到你的问题中,每行缩进4个空格。读取文件时很难回溯,因此要解决您的问题,必须能够区分IPAddress和AssociatedTixes,我无法判断这是否可行,因为您尚未向我们展示数据的真实外观。@martineau,您可以将文件的文本存储在变量中,然后枚举csv文件中的行以查找前一行@pHorseSpec,我不太明白你的意思,但似乎你最终会得到类似行的多个副本,并且csv文件不会被修复。你能提供一个前后对比的例子吗?@Moon:显然,如果先把整件事读入记忆,回首过去不会有什么问题。然而,这样做不应该是一个人对解决这些问题的自动反应,因为所讨论的文件可能是巨大的。无论如何,需要有某种方法来区分此文件中包含的两种类型的数据,以便执行OP所需的操作。因此,在您的示例中,有四种与ip关联的Tix?我怀疑您的文件看起来是这样的。请把它的一部分复制粘贴到你的问题中,每行缩进4个空格。读取文件时很难回溯,因此要解决您的问题,必须能够区分IPAddress和AssociatedTixes,我无法判断这是否可行,因为您尚未向我们展示数据的真实外观。@martineau,您可以将文件的文本存储在变量中,然后枚举csv文件中的行以查找前一行@pHorseSpec,我不太明白你的意思,但似乎你最终会得到类似行的多个副本,并且csv文件不会被修复。你能提供一个前后对比的例子吗?@Moon:显然,如果先把整件事读入记忆,回首过去不会有什么问题。然而,这样做不应该是一个人对解决这些问题的自动反应,因为所讨论的文件可能是巨大的。无论如何,需要有某种方法来区分这一部分中包含的两种类型的数据,以便执行OP想要的操作。