管道分隔符文件,但数据内部没有管道

时间:2015-10-03 09:36:24

标签: python

问题

我需要将文本从逗号(,)分隔值重新格式化为管道(|)分隔值。原始(逗号分隔)文本值内的管道字符应替换为(管道分隔)结果文本中的表示空间。

管道分离结果文本应写回到已读取原始逗号分隔文本的同一文件中。

我正在使用python 2.6

可能的解决方案

我应首先读取该文件并删除所有带有空格的管道,然后用(,)替换(|)。

有没有更好的方法来实现这一目标?

3 个答案:

答案 0 :(得分:3)

不要重新发明价值分离的文件解析轮。使用csv module为您解析写作。

csv模块会在包含分隔符的值周围添加"..."引号,因此原则上您不需要替换值中的|管道符号。要替换原始文件,请写入新的(临时)输出文件,然后将其移回原位。

import csv
import os

outputfile = inputfile + '.tmp'
with open(inputfile, 'rb') as inf, open(outputfile, 'wb') as outf:
    reader = csv.reader(inf)
    writer = csv.writer(outf, delimiter='|')
    writer.writerows(reader)
os.remove(inputfile)
os.rename(outputfile, inputfile)

对于包含以下内容的输入文件:

foo,bar|baz,spam

这会产生

foo|"bar|baz"|spam

请注意,中间列用引号括起来。

如果确实需要替换值中的|个字符,则可以在复制行时执行此操作:

outputfile = inputfile + '.tmp'
with open(inputfile, 'rb') as inf, open(outputfile, 'wb') as outf:
    reader = csv.reader(inf)
    writer = csv.writer(outf, delimiter='|')
    for row in reader:
        writer.writerow([col.replace('|', ' ') for col in row])
os.remove(inputfile)
os.rename(outputfile, inputfile)

现在我的示例的输出变为:

foo|bar baz|spam

答案 1 :(得分:1)

听起来您正在尝试使用CSV的变体 - 在这种情况下,Python's CSV library可能也是您需要的。您可以将它与自定义分隔符一起使用,它将自动为您处理转义(此示例已从手册中删除并已修改):

import csv
with open('eggs.csv', 'wb') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter='|')
    spamwriter.writerow(['One', 'Two', 'Three])

还有一些方法可以修改引用和转义以及其他选项。阅读的作用相似。

答案 2 :(得分:1)

您可以从替换了管道字符的原始文件创建临时文件,然后在处理完成后用原始文件替换原始文件:

import csv
import tempfile
import os

filepath = 'C:/Path/InputFile.csv'

with open(filepath, 'rb') as fin:
    reader = csv.DictReader(fin)
    fout = tempfile.NamedTemporaryFile(dir=os.path.dirname(filepath)
                                       delete=False)
    temp_filepath = fout.name
    writer = csv.DictWriter(fout, reader.fieldnames, delimiter='|')

#   writer.writeheader()  # requires Python 2.7
    header = dict(zip(reader.fieldnames, reader.fieldnames))
    writer.writerow(header)

    for row in reader:
        for k,v in row.items():
            row[k] = v.replace('|'. ' ')
        writer.writerow(row)
    fout.close()

os.remove(filepath)
os.rename(temp_filepath, filepath)