从mysql我使用outfile生成一个以制表符分隔的输出文件。然后我使用python加载tsv并处理它。我觉得我错过了一些内容,但我无法弄清楚如何让csv.reader
接受引用字段可以包含\t
个标签,\n
换行符,{{1}的数据\r
不断突破所有换行符上的行,而不仅仅是我引用字段之外的csv.reader
换行符。
\n
在下面的示例中,with open('/path/to/file.tsv', 'rbU') as f:
reader = csv.reader(
f,
delimiter='\t',
lineterminator='\n',
quoting=csv.QUOTE_ALL
)
for line in reader:
# do something
是实际回车符,\r
是实际换行符,而\n
是mysql输出的空值。
\N
结果输出:
"4256996" "test@gmail.com" "Y " "98230\r" "2012-07-10T12:00:00" "some location" \N \N "false" "aaa" "another-field" "true" 1
有没有办法让['4256996', 'test@gmail.com', 'Y\t', '98230'], ['2012-07-10T12:00:00', 'some location', '\\N', '\\N', 'false', 'aaa', 'another-field', 'true', '1']
正确读取这些输入数据,或者这是csv.reader
对象的某种限制?
注意:如果您尝试复制此内容,请确保将csv.reader
替换为实际回车符,\r
替换为实际换行符等。
答案 0 :(得分:1)
您需要仅以二进制模式打开文件。通过添加'U'
(通用换行模式),您可以指示Python将\r
替换为\n
。
with open('/path/to/file.tsv', 'rb') as f:
一旦读取只二进制数据,您的样本输入就会起作用:
>>> import csv
>>> from io import BytesIO
>>> sample = BytesIO('''\
... "4256996"\t"test@gmail.com"\t"Y "\t"98230\r"\t"2012-07-10T12:00:00"\t"some location"\t\\N\t\\N\t"false"\t"aaa"\t"another-field"\t"true"\t1\r\n''')
>>> sample.readline()
'"4256996"\t"test@gmail.com"\t"Y "\t"98230\r"\t"2012-07-10T12:00:00"\t"some location"\t\\N\t\\N\t"false"\t"aaa"\t"another-field"\t"true"\t1\r\n'
>>> sample.seek(0)
0L
>>> reader = csv.reader(sample, delimiter='\t',
... lineterminator='\n',
... quoting=csv.QUOTE_ALL
... )
>>> next(reader)
['4256996', 'test@gmail.com', 'Y ', '98230\r', '2012-07-10T12:00:00', 'some location', '\\N', '\\N', 'false', 'aaa', 'another-field', 'true', '1']
为了说明,使用U
模式集读取一行,Python会错误地读取数据:
>>> sample.seek(0)
0L
>>> open('/tmp/test.csv', 'wb').write(sample.read())
>>> f = open('/tmp/test.csv', 'rbU')
>>> f.readline()
'"4256996"\t"test@gmail.com"\t"Y "\t"98230\n'
>>> f = open('/tmp/test.csv', 'rb')
>>> f.readline()
'"4256996"\t"test@gmail.com"\t"Y "\t"98230\r"\t"2012-07-10T12:00:00"\t"some location"\t\\N\t\\N\t"false"\t"aaa"\t"another-field"\t"true"\t1\r\n'