sed转换换行符本质是处理\r字符:windows用\r\n、linux用\n,故crlf转lf即删行尾\r(如sed 's/\r$//'),而lf转crlf需先读入整文件再替换\n为\r\n或用awk/unix2dos等更稳妥工具。

Linux 中用 sed 转换换行符格式,本质是处理 \r(回车)这个字符。因为 Linux 原生用 \n(换行),Windows 用 \r\n,所以常见需求是“去掉 \r”或“加上 \r”。但要注意:sed 默认按行读取,自动剥离行尾的 \n,并不把 \n 当作普通字符处理——这意味着你不能直接用 s/\n/\r\n/g 这类写法来添加换行符。
将 Windows 文件(CRLF)转为 Linux(LF)
这是最常用场景:删除每行末尾的 \r,只保留 \n。
-
sed -i 's/\r$//' file.txt—— 直接修改原文件,$确保只删行尾的\r -
sed 's/\r$//' file.txt > newfile.txt—— 输出到新文件,更安全
⚠️ 注意:\r 在终端中可能不可见,建议先用 cat -A file.txt 确认是否显示 ^M$;若文件是 UTF-16 或含 BOM,sed 可能出错,优先用 dos2unix。
将 Linux 文件(LF)转为 Windows(CRLF)
sed 本身不擅长“在每行末尾插入 \r”,因为 $ 是逻辑行尾,不是物理字符位置。可靠做法是:
-
sed -i ':a;N;$!ba;s/\n/\r\n/g' file.txt—— 先读完整个文件到模式空间,再全局替换\n为\r\n(适用于中小文件) -
awk '{printf "%s\r\n", $0}' file.txt > newfile.txt—— 更清晰稳定,推荐用于脚本 -
unix2dos file.txt—— 专有工具,自动处理边界情况(如空行、末尾无换行符等)
为什么 sed 处理换行符容易出错
根本原因在于 sed 的“模式空间”机制:
- sed 每次读入一行时,会自动去掉结尾的
\n,处理完再加回去;\r若存在,则作为普通字符保留在行内 -
s/\n/.../在单行模式下永远不匹配,因为\n已被剥离 - 混合格式文件(部分行是 CRLF,部分是 LF)可能被错误截断或跳过
- 二进制内容或非文本文件用 sed 处理会损坏数据
更稳妥的替代方案
除非环境受限,否则建议优先使用专用工具:
-
dos2unix file.txt和unix2dos file.txt—— 自动识别格式、保留权限、支持批量和备份(-b参数) -
tr -d '\r' linuxfile.txt—— 简单轻量,适合纯文本流处理 - Vim 中打开后执行
:set ff=unix或:set ff=dos再保存 —— 交互式编辑时最直观











