如何在Python中将制表符分隔,管道分隔为CSV文件格式

时间:2009-09-02 09:52:09

标签: python csv

我有一个文本文件(.txt),它可以是制表符分隔格式或管道分隔格式,我需要将其转换为CSV文件格式。我正在使用python 2.6。任何人都可以建议我如何识别文本文件中的分隔符,读取数据然后将其转换为逗号分隔文件。

提前致谢

5 个答案:

答案 0 :(得分:6)

我担心在不知道分隔符的情况下你无法识别分隔符。 CSV的问题是,quoting ESR

  

Microsoft的CSV版本是如何不设计文本文件格式的教科书示例。

如果分隔符可以出现在字段中,则需要以某种方式对其进行转义。在不知道如何完成转义的情况下,自动识别它很困难。可以使用UNIX方式进行转义,使用反斜杠'\'或Microsoft方式,使用引号,然后必须转义。这不是一项微不足道的任务。

所以我的建议是从生成您要转换的文件的人那里获取完整的文档。然后,您可以使用其他答案或某些变体中建议的方法之一。

编辑:

Python提供的csv.Sniffer可以帮助您推断DSV的格式。如果您的输入如下所示(请注意第二行第一个字段中的引用分隔符):

a|b|c
"a|b"|c|d
foo|"bar|baz"|qux

你可以这样做:

import csv

csvfile = open("csvfile.csv")
dialect = csv.Sniffer().sniff(csvfile.read(1024))
csvfile.seek(0)

reader = csv.DictReader(csvfile, dialect=dialect)
for row in reader:
    print row,
# => {'a': 'a|b', 'c': 'd', 'b': 'c'} {'a': 'foo', 'c': 'qux', 'b': 'bar|baz'}
# write records using other dialect

答案 1 :(得分:1)

您的策略可能如下:

  • 使用制表符分隔的csv阅读器和管道分隔的csv阅读器解析文件
  • 计算结果行的一些统计信息,以确定哪个结果集是您要编写的结果集。一个想法可能是计算两个记录集中的字段总数(期望选项卡和管道不常见)。另一个(如果您的数据结构很强,并且您希望每行中的字段数相同)可以测量每行的字段数的标准偏差,并采用具有最小标准差的记录集。

在以下示例中,您可以找到更简单的统计信息(字段总数)

import csv

piperows= []
tabrows = []

#parsing | delimiter
f = open("file", "rb")
readerpipe = csv.reader(f, delimiter = "|")
for row in readerpipe:
 piperows.append(row)
f.close()

#parsing TAB delimiter
f = open("file", "rb")
readertab = csv.reader(f, delimiter = "\t")
for row in readerpipe:
 tabrows.append(row)
f.close()

#in this example, we use the total number of fields as indicator (but it's not guaranteed to work! it depends by the nature of your data)
#count total fields
totfieldspipe = reduce (lambda x,y: x+ y, [len(f) for f in piperows])
totfieldstab = reduce (lambda x,y: x+ y, [len(f) for f in tabrows])

if totfieldspipe > totfieldstab:
 yourrows = piperows
else:
 yourrows = tabrows


#the var yourrows contains the rows, now just write them in any format you like

答案 2 :(得分:0)

喜欢这个

from __future__ import with_statement 
import csv
import re
with open( input, "r" ) as source:
    with open( output, "wb" ) as destination:
        writer= csv.writer( destination )
        for line in input:
            writer.writerow( re.split( '[\t|]', line ) )

答案 3 :(得分:0)

for line in open("file"):
    line=line.strip()
    if "|" in line:
        print ','.join(line.split("|"))
    else:
        print ','.join(line.split("\t"))

答案 4 :(得分:0)

我建议从现有答案中获取一些示例代码,或者更好地使用python中的csv模块并将其更改为首先假设制表符分隔,然后管道分离,并生成两个输出文件逗号分开。然后你可以直观地检查这两个文件,以确定你想要哪一个并选择它。

如果你确实有很多文件,那么你需要尝试找一种方法来检测哪个文件是哪个。
其中一个例子就是:

if "|" in line:

这可能就足够了:如果文件的第一行包含管道,那么整个文件可能是管道分隔的,否则假定是一个制表符分隔文件。

或者修复文件以在第一行中包含一个易于识别的键字段 - 或者第一行包含可以检测到的列标题。