【发布时间】:2023-04-04 15:23:02
【问题描述】:
所以我得到了那些模板,它们都以 LF 结尾,我可以在里面填写一些格式的术语,仍然可以通过 "wb" 打开来获取 LF 文件。
这些模板用于 Windows 机器上的部署脚本中,以在 unix 服务器上进行部署。
问题是,很多人会弄乱这些模板,我 100% 肯定他们中的一些人会在里面放一些 CRLF。
如何使用 Python 将所有 CRLF 转换为 LF?
【问题讨论】:
标签: python python-2.7
所以我得到了那些模板,它们都以 LF 结尾,我可以在里面填写一些格式的术语,仍然可以通过 "wb" 打开来获取 LF 文件。
这些模板用于 Windows 机器上的部署脚本中,以在 unix 服务器上进行部署。
问题是,很多人会弄乱这些模板,我 100% 肯定他们中的一些人会在里面放一些 CRLF。
如何使用 Python 将所有 CRLF 转换为 LF?
【问题讨论】:
标签: python python-2.7
行尾:
\r\n,称为CRLF
\n,称为LF
CRLF ➡ LF)这是一个简短的 Python 脚本,用于将 Windows 行尾直接转换为 Linux/Unix/MacOS 行尾。该脚本就地工作,即无需创建额外的输出文件。
# replacement strings
WINDOWS_LINE_ENDING = b'\r\n'
UNIX_LINE_ENDING = b'\n'
# relative or absolute file path, e.g.:
file_path = r"c:\Users\Username\Desktop\file.txt"
with open(file_path, 'rb') as open_file:
content = open_file.read()
# Windows ➡ Unix
content = content.replace(WINDOWS_LINE_ENDING, UNIX_LINE_ENDING)
# Unix ➡ Windows
# content = content.replace(UNIX_LINE_ENDING, WINDOWS_LINE_ENDING)
with open(file_path, 'wb') as open_file:
open_file.write(content)
LF ➡ CRLF)要将转换从 Linux/Unix/MacOS 更改为 Windows,只需将 Unix ➡ Windows 的替换注释回来(删除行前的 #)。
请勿注释掉Windows ➡ Unix 替换的命令,因为它可以确保正确转换。从LR 转换为CRLF 时,文件中不存在CRLF 行结尾很重要。否则,这些行将被转换为CRCRLF。首先将行从CRLF 转换为LF,然后将行从LF 转换为CRLF 将避免此问题(感谢@neuralmer 指出这一点)。
重要提示:我们需要确保以二进制模式(mode='rb' 和 mode='wb')两次打开文件,才能进行转换。
当以文本模式打开文件时(mode='r' 或 mode='w' 不带b),平台的本机行尾(Windows 上的\r\n 和旧 Mac OS 版本上的\r)会自动转换为 Python 的 Unix -风格的行尾:\n。所以对content.replace() 的调用找不到任何\r\n 行尾要替换。
在二进制模式下,不会进行此类转换。因此,对str.replace() 的调用可以完成它的工作。
在 Python 3 中,如果未另行声明,字符串将存储为 Unicode (UTF-8)。但是我们以二进制模式打开文件 - 因此我们需要在替换字符串前面添加 b 以告诉 Python 也将这些字符串作为二进制处理。
在 Windows 上,路径分隔符是反斜杠 \,我们需要在普通 Python 字符串中使用 \\ 对其进行转义。通过在字符串前面添加r,我们创建了一个不需要任何转义的所谓“原始字符串”。因此,您可以直接将路径从 Windows 资源管理器复制/粘贴到您的脚本中。
(提示:在 Windows 资源管理器中按 CTRL+L 自动从地址栏中选择路径。)
我们打开文件两次以避免重新定位文件指针。我们也可以使用mode='rb+' 打开文件一次,但是我们需要在读取其内容 (open_file.seek(0)) 后将指针移回开始并在写入新内容之前截断其原始内容 (open_file.truncate(0))。
只需在写入模式下再次打开文件,我们就会自动完成。
干杯和快乐的编程,
眨眼
【讨论】:
content,因此无法以二进制模式读取。基本上我有一个“多行字符串”。因此,我得到TypeError: replace() argument 1 must be str, not bytes。有解决办法吗?
byte_str = your_str.encode("UTF-8")。然后替换byte_str 的行尾。要将其转换回字符串,请使用:your_new_str = byte_str.decode("UTF-8").
opening files in text mode (mode='r' or mode='w' without b), the platform's native line endings (\r\n on Windows and \r on old Mac OS versions) are automatically converted to Python's Unix-style line endings: \n
open 的默认换行符类型是通用的,在这种情况下,它不介意每行有哪种换行符。
您还可以使用 newline 参数为 open 请求特定形式的换行符。
因此在 Python 中从一种形式转换为另一种形式相当简单:
with open('filename.in', 'r') as infile, \
open('filename.out', 'w', newline='\n') as outfile:
outfile.writelines(infile.readlines())
open 函数通过'rU' 模式支持universal newlines。
再次,从一种形式转换为另一种形式:
with open('filename.in', 'rU') as infile, \
open('filename.out', 'w', newline='\n') as outfile:
outfile.writelines(infile.readlines())
(在 Python 3 中,模式 U 实际上已被弃用;等效形式为 newline=None,这是默认的)
【讨论】:
你为什么不试试下面:
str.replace('\r\n','\n');
CRLF => \r\nLF => \n
【讨论】:
newline 参数,如赞成的答案所示。
可以用以下代码来修复现有的模板:
with open('file.tpl') as template:
lines = [line.replace('\r\n', '\n') for line in template]
with open('file.tpl', 'w') as template:
template.writelines(lines)
【讨论】: