修复CSV文件';Python中的s格式
所以我打开了一个csv文件进行解析,但是csv中的某些行的格式不正确。csv格式通常如下所示:修复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)当
'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想要的操作。