python tab分隔文件解析问题

时间:2014-10-01 16:56:14

标签: python python-2.7 csv

从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替换为实际换行符等。

1 个答案:

答案 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'