Python从CSV文件中移除换行符

k3fezbri  于 2023-03-15  发布在  Python
关注(0)|答案(2)|浏览(243)

当我在记事本++中打开CSV文件时,它显示编码是ANSI,并且换行符显示为LF。我尝试通过python删除这些换行符,但没有找到解决方案。我尝试过几个解决方案:

with open(csvTable, 'r') as f:
    raw_csv = f.read()
    clean_csv = raw_csv.strip()

with open(csvTable2, 'w') as f:
    f.write(clean_csv)

以及:

data_set = pd.read_csv(data_file,skip_blank_lines=True, encoding='ANSI')
data_set.to_csv(target_file,index=False)

有人能给我指一下正确的方向吗?

6rqinv9w

6rqinv9w1#

您可以(并且应该)使用csv模块进行任何与CSV相关的工作;除了允许你控制行终止符之外,它还将保留可能存在于一个“单元格”中的内部换行符。
以下内容:

  • 打开输入CSV并创建输出CSV,两者都使用CP-1252(Windows-1252或“ANSI”)编码
  • newline=""指令告诉由open()创建的文件处理程序在读写文件时不要对换行符做任何操作;csv模块的读取器和写入器将处理所有换行符
  • 重要的是,单元格内的换行符将保持原样,而行末尾的换行符(“行终止符”)将设置为CRLF,lineterminator="\r\n"
import csv

ANSI = "cp1252"

with (
    open("input.csv", encoding=ANSI, newline="") as f_in,
    open("output.csv", "w", encoding=ANSI, newline="") as f_out,
):
    reader = csv.reader(f_in)
    writer = csv.writer(f_out, lineterminator="\r\n")
    for row in reader:
        writer.writerow(row)

下面是我的输入.csv:

Col1,Col2
"à
ÿ",1
b,2
c,3

从hexdump来看:

00000000  43 6f 6c 31 2c 43 6f 6c  32 0a 22 e0 0a ff 22 2c  |Col1,Col2."�.�",|
00000010  31 0a 62 2c 32 0a 63 2c  33                       |1.b,2.c,3|
00000019

我们可以看到,行结束符是LF(0a),根据CP-1252,à和字符被编码为e0和ff。
下面是输出.csv:

Col1,Col2
"à
ÿ",1
b,2
c,3

用肉眼看起来是一样的;下面是它在hexdump中的样子:

00000000  43 6f 6c 31 2c 43 6f 6c  32 0d 0a 22 e0 0a ff 22  |Col1,Col2.."�.�"|
00000010  2c 31 0d 0a 62 2c 32 0d  0a 63 2c 33 0d 0a        |,1..b,2..c,3..|
0000001e

我们可以看到:

  • à和仍编码为e0和ff,保留CP-1252编码
  • à和之间的内部换行符保留为0a(LF)
  • 将线终止子转换为0 d 0a(CRLF)
sxissh06

sxissh062#

我最终使用这篇文章来创建一个解决方案:Replace CRLF with LF in Python 3.6它也帮助我度过了难关,并提供了对引擎盖下发生的事情的了解。

OldFile=r"c:\Test\input.csv"
NewFile=r"C:\Test\output.csv"

#reading it in as binary keeps the cr lf in windows as is
with (
    open(OldFile, 'rb') as f_in,
    open(NewFile, 'wb') as f_out,
):

FileContent = f_in.read()

#removing all line breaks including the ones after the carriage return
oldLineFeed = b'\n'
newLineFeed = b''

FileContent = FileContent.replace(oldLineFeed, newLineFeed)

#only have a carriage return now at the end of each true line, added back in the line break 
oldLineFeed = b'\r'
newLineFeed = b'\r\n'
FileContent = FileContent.replace(oldLineFeed, newLineFeed)

f_out.write(FileContent)

f_in.close()
f_out.close()

相关问题