【问题标题】:Removing newline from a csv file从 csv 文件中删除换行符
【发布时间】:2013-01-17 23:37:41
【问题描述】:

我正在尝试在 python 中处理一个 csv 文件,该文件在每行/行的中间有一个 ^M 字符,这是一个换行符。我无法以“rU”以外的任何模式打开文件。

如果我确实以“rU”模式打开文件,它会读取换行符并拆分文件(创建换行符)并给我两倍的行数。

我想完全删除换行符。怎么样?

【问题讨论】:

  • dos2unix 是你想要的。

标签: python newline


【解决方案1】:

请注意,正如the docs 所说:

csvfile 可以是任何支持迭代器协议并在每次调用其next() 方法时返回一个字符串的对象——文件对象和列表对象都适用。

因此,您始终可以在将文件交给reader 或DictReader 之前在文件上添加过滤器。而不是这个:

with open('myfile.csv', 'rU') as myfile:
    for row in csv.reader(myfile):

这样做:

with open('myfile.csv', 'rU') as myfile:
    filtered = (line.replace('\r', '') for line in myfile)
    for row in csv.reader(filtered):

'\r' 是 Python(和 C)拼写 ^M 的方式。所以,这只是将所有^M 字符去掉,无论它们出现在哪里,将每个字符替换为一个空字符串。


我想我想永久修改文件而不是过滤它。

首先,如果您想在运行 Python 脚本之前修改文件,为什么不从 Python 外部进行呢? sed、tr、很多文本编辑器等都可以为你做到这一点。这是一个 GNU sed 示例:

gsed -i'' 's/\r//g' myfile.csv

但是如果你想用 Python 来做,它并没有那么冗长,而且你可能会发现它更具可读性,所以:

首先,如果您想从中间插入或删除,您无法真正就地修改文件。通常的解决方案是编写一个新文件,然后将新文件移到旧文件上(仅限 Unix)或删除旧文件(跨平台)。

跨平台版本:

os.rename('myfile.csv', 'myfile.csv.bak')
with open('myfile.csv.bak', 'rU') as infile, open('myfile.csv', 'wU') as outfile:
    for line in infile:
        outfile.write(line.replace('\r'))
os.remove('myfile.csv.bak')

不太笨重但仅适用于 Unix 的版本:

temp = tempfile.NamedTemporaryFile(delete=False)
with open('myfile.csv', 'rU') as myfile, closing(temp):
    for line in myfile:
        temp.write(line.replace('\r'))
os.rename(tempfile.name, 'myfile.csv')

【讨论】:

  • 我想我想永久修改文件而不是过滤它。您的代码过滤它,但有没有办法例如打开文件并删除 ^M 并关闭它,从而永久修改它?例如在上面,一旦我打印了行,我就会看到换行符。不知道我错过了什么。我的意思是我总是可以在 rU 中打开文件并创建一个新文件并将行附加到它,在原始文件中为 2 行创建 1 行。非常感谢。
  • @dqr:我不确定我是否理解您的跟进,但我会尝试更新答案。
  • @abarnert:当我运行解决方案的 python 版本时出现以下错误:ValueError:通用换行模式只能用于以“r”开头的模式。你知道为什么吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 2020-05-27
相关资源
最近更新 更多