【问题标题】:Using python to write text files with DOS line endings on linux在linux上使用python编写带有DOS行尾的文本文件
【发布时间】:2011-02-08 04:19:51
【问题描述】:

我想使用在 Linux 上运行的 python 来编写带有 DOS/Windows 行尾“\r\n”的文本文件。在我看来,必须有比手动在每行末尾添加 '\r\n' 或使用行尾转换实用程序更好的方法。理想情况下,我希望能够执行一些操作,例如将写入文件时要使用的分隔符分配给 os.linesep。或者在我打开文件时指定行分隔符。

【问题讨论】:

  • 从众多“你可以写...”的答案来看,Python 中没有 os.lineEnding 功能。您似乎必须自己编写一些东西,在这种情况下,您选择“\r\n”或“\n”的想法与任何方法一样好。对于写入文件,似乎这是唯一的方法。

标签: python windows newline


【解决方案1】:

对于 Python 2.6 及更高版本,io 模块中的 open 函数有一个可选的换行参数,可让您指定要使用的换行符。

例如:

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

【讨论】:

  • 您能否接受这个(您的)答案而不是当前接受的答案?对于那些停留在 2.5 或更低版本的人来说,将另一个留在身边很好,但我认为这对大多数人来说是更好的答案。
  • 在python3中你可以使用内置的opennewline参数
【解决方案2】:

您可以查看此PEP 以获得一些参考。

更新:

@OP,你可以尝试创建这样的东西

import sys
plat={"win32":"\r\n", 'linux':"\n" } # add macos as well
platform=sys.platform
...
o.write( line + plat[platform] )

【讨论】:

  • "没有特别支持输出到具有不同换行约定的文件,因此模式 "wU" 也是非法的。"
  • PEP 是关于读取文件,它所说的关于输出的只是,“没有特别支持输出到具有不同换行约定的文件”
  • 我以为你只需要写一种格式,例如linux上的“\n”,然后在windows上使用“U”模式,它就会识别吗?如果不是,我对 PEP 的误解很糟糕。
  • 不,你说得对,但有时需要真正的 CRLF。
  • 我认为 PEP 很好地处理了您在一个平台上生成文件以在该平台上使用的情况。但我需要在 linux 上制作它们,即一个服务器,用于分发给包括 windows 在内的各种操作系统的用户。
【解决方案3】:

只需编写一个类文件,它包装另一个类文件并在写入时将\n 转换为\r\n

例如:

class ForcedCrLfFile(file):
    def write(self, s):
        super(ForcedCrLfFile, self).write(s.replace(r'\n', '\r\n'))

【讨论】:

  • 似乎是python 2.5及更早版本的最佳答案
  • def write(self, s): parent.write(self, s.replace(r'\n', '\r\n'))
  • 如果您将其编辑为答案,我可以将我的投票改为赞成票。
【解决方案4】:

这是我写的一个 python 脚本。它从给定目录递归,用 \r\n 结尾替换所有 \n 行结尾。像这样使用它:

unix2windows /path/to/some/directory

它会忽略文件夹中以“.”开头的文件。它还使用 J.F. Sebastian 在this answer 中给出的方法忽略它认为是二进制文件的文件。您可以使用可选的正则表达式位置参数进一步过滤:

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

这是完整的脚本。为免生疑问,我的零件在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))

【讨论】:

    【解决方案5】:

    您可以编写一个转换文本然后写入的函数。例如:

    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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-18
      相关资源
      最近更新 更多