You can (and should) use the csv module for any CSV-related work; beyond allowing you to control the lineterminator, it will also preserve the internal line breaks that may exist inside a "cell".
The following:
opens your input CSV and creates an output CSV, both with the CP-1252 (Windows-1252 or "ANSI") encoding
the newline=""
directive tells the file handlers created by open() not to do anything with newlines as the files are being read and written; the csv module's reader and writer will handle all newline characters
importantly, newlines inside a cell will be left as is, while the newline at the end of a row (the "line terminator") will be set CRLF with 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)
Here's my input.csv:
Col1,Col2
"à
ÿ",1
b,2
c,3
Looking at it from 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
we can see that we have LF (0a) for the line terminators, and the à and ÿ characters are encoded as e0 and ff, according to CP-1252.
Here's ouptut.csv:
Col1,Col2
"à
ÿ",1
b,2
c,3
Looks to the same to the naked eye; here's how it looks from 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
We can see:
the à and ÿ are still encoded as e0 and ff, the CP-1252 encoding was kept
the internal newline between à and ÿ was kept as 0a (LF)
the line terminators were converted to 0d 0a (CRLF)