Windows (CRLF, \r\n, 0x0D0A) 與 Linux/Unix (LF, \n, 0x0A) 換行符差異導致文件在 Linux 顯示 ^M (Ctrl+V Ctrl+M 輸入)。本文提供 file 檢測、vi/sed 替換、dos2unix 專用工具、批量處理、編碼轉換全方案。
file filename
# 輸出示例:
# test.txt: ASCII text # 純 LF (Unix)
# test.txt: ASCII text, with CRLF line terminators # 帶 ^M (Windows)
# test.txt: UTF-8 Unicode text, with CRLF line terminators
cat -A file:$ 顯示行尾,^M$ 即 CRLF。hexdump -C file | head:查看原始十六進制 0d 0a vs 0a。
# 進入 vi 文件,命令模式輸入:
:%s/\r//g # 刪除所有 \r (^M) —— 推薦
:%s/\r$//g # 僅刪除行尾 \r
:%s/\r/\r/g # 替換 \r 為換行 (極少用)
# 輸入 \r 方法: Ctrl+V 然後 Ctrl+M (顯示 ^M)
# 或直接輸入: %s///g
# 覆蓋原文件 (需 GNU sed -i 支持)
sed -i 's/\r//g' filename
# 或
sed -i 's/\r$//' filename
# 生成新文件,保留原文件
sed 's/\r//g' oldfile > newfile
# 處理多文件
find . -name "*.txt" -exec sed -i 's/\r//g' {} +
注意:macOS/BSD sed 需 sed -i '' 's/\r//g' file。
# 安裝
yum install -y dos2unix # RHEL系
apt install -y dos2unix # Debian系
# 單文件轉換 (默認覆蓋原文件)
dos2unix filename
# 保留原文件時間戳
dos2unix -k filename
# 生成新文件,不修改原文件
dos2unix -n oldfile newfile
# 批量轉換
dos2unix file1 file2 file3 ...
find . -type f -name "*.sh" -exec dos2unix {} +
# 反向轉換 (Linux → Windows)
unix2dos filename
# 參數同 dos2unix
優勢:自動處理編碼、保留權限/時間戳選項、報告轉換統計、兼容性最好。
cat win.txt | tr -d '\r' > linux.txt
# 或
tr -d '\r' < win.txt > linux.txt
Windows 文件常為 GBK/GB2312 編碼 + CRLF。Linux 需 UTF-8 + LF:
# 一步到位: 編碼轉換 + 去除 ^M
iconv -f GBK -t UTF-8 win.txt | tr -d '\r' > linux.txt
# 或 dos2unix 支持編碼轉換 (新版)
dos2unix --encoding=GBK --output=linux.txt win.txt
在倉庫根目錄創建 .gitattributes:
* text=auto
*.sh text eol=lf
*.py text eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
text=auto:Git 自動檢測文本文件,checkout 時轉換為 LF,commit 時轉換為 LF (核心規範)。git config --global core.autocrlf input (Linux/Mac) / true (Windows)。| 場景 | 推薦工具 | 理由 |
|---|---|---|
| 單文件交互編輯 | vi :%s/\r//g | 直觀、可撤銷 |
| 腳本/批量/管道處理 | dos2unix -k / sed -i | 高效、保留元數據、報告統計 |
| 編碼+換行符雙重轉換 | iconv | tr / dos2unix --encoding | 一步到位 |
| 團隊協作根治 | .gitattributes + core.autocrlf | 源頭治理,跨平台無感 |
