Использование Python для записи текстовых файлов с окончаниями строк DOS в Linux

Я хочу писать текстовые файлы с окончанием строки DOS / Windows '\ r \ n', используя python, работающий в Linux. Мне кажется, что должен быть лучший способ, чем вручную помещать '\ r \ n' в конце каждой строки или использовать утилиту преобразования конца строки. В идеале я хотел бы иметь возможность сделать что-то вроде присвоения os.linesep разделителя, который я хочу использовать при записи файла. Или укажите разделитель строк при открытии файла.


person gaumann    schedule 15.04.2010    source источник
comment
Судя по многочисленным ответам, которые вы могли бы написать ..., в Python нет os.lineEnding функции. Кажется, вы должны написать что-то самостоятельно, и в этом случае ваша идея выбора \ r \ n или \ n будет таким же хорошим методом, как и любой другой. Для записи файла, кажется, это единственный способ.   -  person Demis    schedule 01.12.2015


Ответы (5)


Просто напишите файл, подобный файлу, который обертывает другой файл и преобразует \n в \r\n при записи.

Например:

class ForcedCrLfFile(file):
    def write(self, s):
        super(ForcedCrLfFile, self).write(s.replace(r'\n', '\r\n'))
person Ignacio Vazquez-Abrams    schedule 15.04.2010
comment
кажется лучшим ответом для python 2.5 и ранее - person gaumann; 15.04.2010
comment
Если вы отредактируете это в ответе, я могу изменить свой голос на положительный. - person Theo Belaire; 05.11.2014

Для Python 2.6 и более поздних версий функция open в модуле io имеет необязательный параметр новой строки, который позволяет указать, какие новые строки вы хотите использовать.

Например:

import io
with io.open('tmpfile', 'w', newline='\r\n') as f:
    f.write(u'foo\nbar\nbaz\n')

создаст файл, содержащий это:

foo\r\n
bar\r\n
baz\r\n
person gaumann    schedule 15.04.2010
comment
Не могли бы вы принять этот (ваш) ответ вместо принятого в настоящее время? Можно оставить второй вариант для тех, кто застрял на 2,5 или ниже, но я думаю, что это гораздо лучший ответ для большинства людей. - person Henrik Heimbuerger; 25.05.2015
comment
В python3 вы можете использовать встроенный open с параметром newline - person johnson; 13.12.2016

вы можете ознакомиться с этим PEP для справки.

Обновлять:

@OP, вы можете попробовать создать что-то вроде этого

import sys
plat={"win32":"\r\n", 'linux':"\n" } # add macos as well
platform=sys.platform
...
o.write( line + plat[platform] )
person ghostdog74    schedule 15.04.2010
comment
Нет специальной поддержки для вывода в файл с другим соглашением о новой строке, поэтому режим wU также недопустим. - person Ignacio Vazquez-Abrams; 15.04.2010
comment
Этот PEP предназначен для чтения файлов, и все, что он говорит о выводе, это: нет специальной поддержки вывода в файл с другим соглашением о новой строке. - person gaumann; 15.04.2010
comment
Я думал, вам просто нужно написать только один формат, например \ n в Linux, а затем использовать режим U в Windows, и он распознает? если нет, то плохо, что я неверно истолковал PEP. - person ghostdog74; 15.04.2010
comment
Нет, в этом вы правы, но иногда нужен настоящий CRLF. - person Ignacio Vazquez-Abrams; 15.04.2010
comment
Я думаю, что PEP хорошо справляется с ситуацией, когда вы создаете файлы на одной платформе для использования на этой платформе. Но мне нужно производить их на Linux, то есть на сервере для распространения среди пользователей различных операционных систем, включая Windows. - person gaumann; 15.04.2010
comment
я понимаю. ну, если это так, использование вручную \r\n неизбежно. - person ghostdog74; 15.04.2010

Вот сценарий на Python, который я написал. Он рекурсивно переходит из заданного каталога, заменяя все окончания строк \ n на окончания \ r \ n. Используйте это так:

unix2windows /path/to/some/directory

Он игнорирует файлы в папках, начинающиеся с символа ".". Он также игнорирует файлы, которые он считает двоичными, используя подход, предложенный Дж. Ф. Себастьяном в этом ответе. Вы можете фильтровать дальше, используя необязательный позиционный аргумент регулярного выражения:

unix2windows /path/to/some/directory .py$

Вот сценарий полностью. Во избежание сомнений, мои детали лицензированы в соответствии с лицензией MIT.

#!/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))
person Martin Eden    schedule 19.05.2016

Вы можете написать функцию, которая преобразует текст, а затем записывает его. Например:

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()
person Community    schedule 15.04.2010