I want to write text files with DOS/Windows line endings '\r\n' using python running on Linux. It seems to me that there must be a better way than manually putting a '\r\n' at the end of every line or using a line ending conversion utility. Ideally I would like to be able to do something like assign to os.linesep the separator that I want to use when writing the file. Or specify the line separator when I open the file.
-
Judging from the numerous "you could write..." answers, there is no `os.lineEnding` feature in Python. You have to write something yourself it seems, in which case your idea of choosing "\r\n" or "\n" is as good a method as any. For writing a file, it seems this is the only way. – Demis Dec 01 '15 at 01:23
5 Answers
For Python 2.6 and later, the open function in the io
module has an optional newline parameter that lets you specify which newlines you want to use.
For example:
import io
with io.open('tmpfile', 'w', newline='\r\n') as f:
f.write(u'foo\nbar\nbaz\n')
will create a file that contains this:
foo\r\n
bar\r\n
baz\r\n

- 9,924
- 6
- 56
- 69

- 1,183
- 1
- 7
- 9
-
10Can you please accept this (your) answer instead of the currently accepted one? It's fine to leave the other one around for those stuck on 2.5 or lower, but I think this is the much better answer for the majority of people. – Henrik Heimbuerger May 24 '15 at 22:18
-
8In python3 you can use the built-in `open` with the `newline` parameter – johnson Dec 13 '16 at 08:49
you can look at this PEP for some reference.
Update:
@OP, you can try creating something like this
import sys
plat={"win32":"\r\n", 'linux':"\n" } # add macos as well
platform=sys.platform
...
o.write( line + plat[platform] )

- 327,991
- 56
- 259
- 343
-
"There is no special support for output to file with a different newline convention, and so mode "wU" is also illegal." – Ignacio Vazquez-Abrams Apr 15 '10 at 01:01
-
That PEP is about reading files all it says about output is, "There is no special support for output to file with a different newline convention" – gaumann Apr 15 '10 at 01:04
-
i thought you just need to write just one format, eg "\n" on linux and then use the "U" mode on windows and it will recognise? if not, my bad for misinterpreting the PEP. – ghostdog74 Apr 15 '10 at 01:05
-
No, you're right about that, but sometimes a real CRLF is needed. – Ignacio Vazquez-Abrams Apr 15 '10 at 01:06
-
I think the PEP nicely deals with the situation where you produce the files on one platform to use on that platform. But I need to produce them on linux i.e. a server for distribution to users of various operating systems including windows. – gaumann Apr 15 '10 at 01:08
-
i see. well, if that's the case, using manually `\r\n` is inevitable. – ghostdog74 Apr 15 '10 at 01:08
Just write a file-like that wraps another file-like and which converts \n
to \r\n
on write.
For example:
class ForcedCrLfFile(file):
def write(self, s):
super(ForcedCrLfFile, self).write(s.replace(r'\n', '\r\n'))

- 12,318
- 7
- 50
- 72

- 776,304
- 153
- 1,341
- 1,358
-
1
-
2`def write(self, s):` `parent.write(self, s.replace(r'\n', '\r\n'))` – Ignacio Vazquez-Abrams Oct 30 '14 at 16:57
-
If you edit that into the answer, I can change my vote to an upvote. – Theo Belaire Nov 05 '14 at 14:17
Here's a python script I wrote. It recurses from a given directory, replacing all \n line endings with \r\n endings. Use it like this:
unix2windows /path/to/some/directory
It ignores files in folders beginning with a '.'. It also ignores files that it thinks are binary files, using the approach given by J.F. Sebastian in this answer. You can filter further by using the optional regex positional argument:
unix2windows /path/to/some/directory .py$
Here's the script in full. For the avoidance of doubt, my parts are licensed under the MIT licence.
#!/usr/bin/python
import sys
import os
import re
from os.path import join
textchars = bytearray({7,8,9,10,12,13,27} | set(range(0x20, 0x100)) - {0x7f})
def is_binary_string(bytes):
return bool(bytes.translate(None, textchars))
def is_binary_file(path):
with open(path, 'rb') as f:
return is_binary_string(f.read(1024))
def convert_file(path):
if not is_binary_file(path):
with open(path, 'r') as f:
text = f.read()
print path
with open(path, 'wb') as f:
f.write(text.replace('\r', '').replace('\n', '\r\n'))
def convert_dir(root_path, pattern):
for root, dirs, files in os.walk(root_path):
for filename in files:
if pattern.search(filename):
path = join(root, filename)
convert_file(path)
# Don't walk hidden dirs
for dir in list(dirs):
if dir[0] == '.':
dirs.remove(dir)
args = sys.argv
if len(args) <= 1 or len(args) > 3:
print "This tool recursively converts files from Unix line endings to"
print "Windows line endings"
print ""
print "USAGE: unix2windows.py PATH [REGEX]"
print "Path: The directory to begin recursively searching from"
print "Regex (optional): Only files matching this regex will be modified"
print ""
else:
root_path = sys.argv[1]
if len(args) == 3:
pattern = sys.argv[2]
else:
pattern = r"."
convert_dir(root_path, re.compile(pattern))

- 1
- 1

- 6,143
- 3
- 30
- 33
You could write a function that converts text then writes it. For example:
def DOSwrite(f, text):
t2 = text.replace('\n', '\r\n')
f.write(t2)
#example
f = open('/path/to/file')
DOSwrite(f, "line 1\nline 2")
f.close()