跳过主要内容
全部文章

换行符 CRLF 和 LF 有什么区别?

了解 CRLF 和 LF 换行符的区别,以及 Windows、Mac、Linux 中的常见用法。附 Git 提示、脚本 ^M 报错和换行符转换方法。

基础知识

CRLF 和 LF 的区别

CRLF 用回车和换行两个字符 \r\n 标记一次换行,LF 只用一个字符 \n。 在大多数编辑器里,两种方式看起来一样。导入工具、Git 或脚本解释器处理的是文件中的实际字符,所以有时需要指定一种格式。

\r 和 \n 是什么?

\r 叫回车(Carriage Return,CR),在 ASCII 和 UTF-8 中对应十六进制 0D。\n 叫换行(Line Feed,LF),对应 0A。这些名称来自机械打字和打印设备。回车让打字位置回到一行的开头,送纸让纸向前走一行。两个动作配合,就能从下一行开头继续输入。

以 UTF-8 文件为例,假设两行各有一个字母,第二行末尾没有换行:

换行约定用转义写法表示文件里的十六进制字节
LFA\nB41 0A 42
CRLFA\r\nB41 0D 0A 42
CRA\rB41 0D 42

直接在编辑器里打出反斜杠和字母 n,会保存为两个可见字符。按 Enter 才会按编辑器的设置写入实际的行尾字符。上表的字节例子也依赖 UTF-8,UTF-16 等编码会用不同的字节表示这些字符。

各系统默认用什么换行符?

系统或环境常见换行符常见来源
WindowsCRLF(\r\n)系统工具或某些办公软件导出的文本
macOS、Linux、UnixLF(\n)Shell 脚本、源码、普通文本
早期 Mac OSCR(\r)Mac OS X 之前的旧文件

这只是系统和软件的常见约定。从 Linux 发到 Windows 的 TXT,原有的 LF 不会因为收件设备变了就自动改成 CRLF。新版 Windows 记事本支持识别 LF 和 CR。旧机器上的记事本或者某些导入工具仍可能只按 CRLF 处理。微软关于记事本支持更多换行符的公告

换行符引起的常见问题

Shell 脚本报错 ^M 是怎么回事?

如果在 Windows 上编辑 Shell 脚本后,Linux 报出类似 /bin/bash^M: bad interpreter 的信息,检查脚本第一行。假设第一行是 #!/bin/bash,结尾多出来的 CR 可能被当作解释器路径的一部分。日志里的 ^M 表示 CR。把脚本统一转成 LF,再到实际运行环境测试。如果通过 Git 或打包工具分发,出问题的也可能是交付副本。

Git 提示 LF will be replaced by CRLF 是什么意思?

这条提示通常说明 Git 会根据当前规则,在将来写入工作区时把 LF 转成 CRLF。仓库里暂存的内容可以使用 LF,检出后工作区文件可以有另一种格式。先查看项目的 .gitattributes 和本地 core.autocrlf 配置,再判断文件要保持哪种格式。只改了一句话却发现整个文件都在 diff 里变化时,也可以先排查行尾是否被编辑器统一转换了。Git 属性文档

CSV 导入后为什么只有一行?

有些系统按固定的行尾拆分记录。如果导入器只认识 CRLF,使用 LF 的文件可能被当成一条记录。RFC 4180 描述的 CSV 用 CRLF 分隔记录,但软件支持的格式可能更宽松。还要检查分隔符和引号,例如带引号的备注字段可以包含换行。验证时用能识别 CSV 规则的程序核对行数,避免把字段内的换行当成记录结束。RFC 4180 的 CSV 格式说明

记事本里怎么全挤在一行?

旧版记事本可能无法正确显示 LF。先换支持 LF 的编辑器确认文件里的段落,再判断有没有必要转换。如果汉字本身已经乱码,要先排查读取编码。换行设置解决的是行边界,可以参考 TXT 文件的编码说明。

如何查看和转换换行符?

在 VS Code 或 Notepad++ 里检查

  1. VS Code 打开文件后,在底部状态栏查看 LF 或 CRLF。点击这个标识,选所需格式,再保存。VS Code 状态栏的实现
  2. Notepad++ 可以通过 编辑 › 文档格式转换(Edit › EOL Conversion),选择 Unix (LF) 或 Windows (CR LF) 后保存。Macintosh (CR) 对应早期 Mac 格式。Notepad++ 编辑手册

状态栏通常显示当前识别或选中的格式。如果怀疑同一文件前半段是 CRLF、后半段是 LF,可以用十六进制视图查看几处行尾。对 UTF-8 而言,0D 0A 是 CRLF,单独的 0A 是 LF。这样还能区分实际换行和窗口里显示出来的自动折行。

用 dos2unix 和 unix2dos 转换

已安装 dos2unix 工具时,可以用 -n 指定输入和输出文件,保留原件。下面第一条把 Windows 风格文本转成 LF,第二条把 Unix 风格文本转成 CRLF。

dos2unix -n windows.txt unix-copy.txt
unix2dos -n unix.txt windows-copy.txt

示例适合常见的 UTF-8 输入。处理 UTF-16 或要求保留 BOM 的文件前,先核对工具对编码和 BOM 的默认处理。转换后用实际接收程序打开一遍,确认正文、行数和字符都对。dos2unix 命令手册

用 .gitattributes 约定仓库格式

在使用文本自动转换的情况下,core.autocrlf=true 可以让 Git 将文本规范为 LF 后存入索引,再以 CRLF 检出。core.autocrlf=input 做入库转换,检出时不要求改成 CRLF。团队项目可以把规则写入 .gitattributes,让使用不同系统的人共享同一份约定。例如下面这行对识别为文本的文件指定工作区使用 LF:

* text=auto eol=lf

如果只需要约束 Shell 脚本,也可以把规则限制到 *.sh。添加规则后,已跟踪的文件可能还要按 Git 文档执行重新规范化。涉及大量文件时,可以把行尾转换集中在一次独立改动中,便于核对正文。Git 配置文档,Git 属性文档

该选 CRLF 还是 LF?

  • 交给某个导入系统时,按它写明的格式选。
  • 写给 Linux 或 macOS 上运行的 Shell 脚本时,用 LF。
  • 在已有代码仓库里,沿用仓库规则。
  • 给旧版 Windows 工具准备文件时,如果它要求 CRLF,就导出 CRLF。
  • 普通纯文本在多个现代编辑器之间使用时,可以从 UTF-8 和 LF 开始。

如果接收系统只给了一份可以成功导入的样例,可以先检查样例的换行和编码,再用两三行真实数据试传。只用英文测试时,可能看不出中文读取的问题。测试文件也可以包含一条最长的记录,以便区分自动折行和真实换行。

在线生成指定换行符的 TXT 文件

在在线 TXT 编辑器输入或粘贴文字,在 换行符 选项里选 LF 或 CRLF,再填写文件名并下载。中文内容通常选 UTF-8,编码和换行符可以分别设置。已经有原文件时,先另存新版本,导入成功后再处理旧稿。

常见问题

CRLF 算两行还是一行?

CR 和 LF 合在一起表示一次换行。连续两组 CRLF 才表示连续两次换行。

文件最后一行一定要有换行吗?

按文件格式和接收工具的约定。有些源码或脚本工具希望文件最后一行以换行结束,后续追加内容也比较方便。部分数据格式允许最后一条记录不带换行。

换行符和空行有什么区别?

换行符标记一行结束。在两段文字之间连续插入两个换行,可以留下一个空行。如果只是编辑器根据窗口宽度自动折行,文件里没有新增换行。

转成 CRLF 后文件会大多少?

在 UTF-8 文件里,每处从 LF 改成 CRLF 的行尾会多一个字节。比如转换一百处,正文、编码和 BOM 都不变时,文件会增加一百字节。