1. 源起

换行符(newline)这个看似简单的概念,其实有着相当长的历史。换行符来自老式打字机

老式打字机

早期的打字机具有一个可左右移动的”字头滑架(carriage)“结构,用来让字槌在纸上敲出对应的字符。在排版时,文字依序从左到右、从上到下输出,因此当一行被打满后需要做两件事:

  • 将纸张往上滚动一行 — line feed(LF)
  • 将字头滑架移回最左边 — carriage return(CR)

这两个动作本质上都是”控制机械位置”,而不是”输出文字”。为了简化操作,在键盘上只需要按下一个 Enter 键即可一次完成两个动作。

2. 电脑时代的延续:\n 与 \r

到了电子计算机时代,键盘与打字机的设计一脉相承,CR 与 LF 也一起被编入 ASCII 表。对应如下:

  • \n → line feed(换到下一行)
  • \r → carriage return(回到行首)

因为早期存储空间昂贵,不同系统对”换行”采用了不同的组合方式,以节省空间或维持兼容性。这两个字符都占一个长度。但早期计算机存储非常昂贵,两个字符表示换行符占据空间太多,不同系统就有了自己的设计:

简写全名符号系统记忆方式
crcarriage return\rmacmac 中有 c
lfline feed\nlinuxlinux 也是以 l 开头的
crlfcarriage return line feed\n\rWindowsmicrosoft 先是 cr 再是 f

3. 遇到问题

因为不同操作系统采用不同的换行符格式,所以当同一份文件跨平台使用时,常会遇到以下问题:

3.1 Windows -> Linux,出现 ^M

在 Linux 环境中打开 Windows(CRLF)文件时,每行行尾常会看到 Hello world^M,这个 ^M 就是 \r(CR)的可视化显示方式。

3.2 Linux -> Windows,换行不正常

Windows 的某些程序假设换行一定是 CRLF,因此遇到只有 \n 的文件时:

  • 可能换行不正确
  • 或整段文字显示成一行

3.3 早期 macOS 格式(仅 CR)

虽然现在较少见,但如果打开只有 \r 的文件(旧版 Mac 格式),部分编辑器可能完全不会换行。

4. 解决办法

  • ✔ 方法 1:使用现代编辑器自动转换(推荐)

如 VS Code、Sublime Text、Notepad++ 都能自动侦测并转换换行格式。例如 VS Code:右下角点选 LF / CRLF → 选择要转换的格式即可。

  • ✔ 方法 2:使用命令行工具转换
# Linux / macOS
dos2unix file.txt # 将 Windows CRLF 转成 Unix LF
unix2dos file.txt # 将 Unix LF 转成 Windows CRLF

手动替换(不推荐,但可用)

# 移除所有 CR (^M)
sed -i 's/\r$//' file.txt
  • ✔ 方法 3:在编程语言内处理(如 Python)

Python 默认会自动识别换行符,但若需要手动处理:

with open("file.txt", "r", newline="") as f:
    content = f.read().replace("\r\n", "\n").replace("\r", "\n")