1. 源起

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

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

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

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

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

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

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

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

简写 全名 符号 系统 记忆方式
cr carriage return \r mac mac 中有 c
lf line feed \n linux linux 也是以 l 开头的
crlf carriage return line feed \n\r Windows microsoft 先是 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")