Linux 中換行符問題

問題

Linux 環(huán)境執(zhí)行一些腳本出錯,查找原因,發(fā)現(xiàn)是文件在Windows環(huán)境修改并上傳,格式被轉(zhuǎn)換為MS-Dos格式(換行符不同),這樣的文件在Linux中運行會出錯(shell 解釋器把換行符作為一個命令的提交)。

背景

很久以前,老式的電傳打字機使用兩個字符來另起新行。回車符(CR)把滑動架移回行首 ,換行符(LF)把紙上移一行 。

teletype.jpg

當計算機問世以后,存儲器曾經(jīng)非常昂貴。有些人就認定沒必要用兩個字符來表示行尾。

UNIX 用 <LF> 一個字符來表示行尾。

Apple 的MacOS 9 及以前用 <CR> ,MacOS 10跟Unix一樣。

MS-DOS (以及Windows) 沿用老式的<CR><LF>,即敲一下回車鍵,相當于同時執(zhí)行了 "回車+換行"。

總結(jié)一下:

系統(tǒng) 中文描述 英文描述 簡寫 轉(zhuǎn)義符
Windows 回車換行 Carriage Return and Line Feed CRLF \n\r
Unix/Linux/Mac OS 換行 Line Feed LF \n

如果你把一個文件從一種系統(tǒng)移到另一種系統(tǒng),那么你就有換行符方面的麻煩。

Windows10的記事本(notepad)能夠自動識別Linux文件,但是在Linux中查看MS-DOS格式文件會發(fā)現(xiàn)每一行的末尾有個 ^M 字符。(^M 就是 <CR>)。

單個文件解決辦法

Linux 環(huán)境下 vim 直接編輯修改文件。

:set fileformat=unix

或者

:set ff=unix

保存退出就解決了。

批量文件解決方案一

這是通用方案,核心邏輯是

  • 找出文件:用file命令查看文件是否有特殊換行符
  • 修改文件:dos2unix命令直接改。(也可以vi 文件修改,后面在舉例)

具體例子

1. 檢查文件

$ file ./test.yml
./test.yml: ASCII text, with CRLF line terminators

輸出中看到了CRLF,這是Dos文件格式的標志。

2. 下一步,文件格式轉(zhuǎn)換

$ dos2unix ./test.yml
dos2unix: converting file ./test.yml to Unix format ...

3. 檢查文件是否真的修改了格式

$ file ./test.yml
./test.yml: ASCII text

發(fā)現(xiàn)沒有CRLF 標志,修改完成。

4. 把上面的命令合并,查找并修改Dos格式文件

$ find . -type f -exec file {} \; | grep CRLF | awk -F: '{print $1}' | xargs dos2unix
dos2unix: converting file ./ansible/README.md to Unix format ...
...

or

$ find . -type f -exec file {} \; | grep CRLF | cut -d : -f 1 | xargs dos2unix

批量文件解決方案二

從 7.1 版本后,dos2unix 有 -i, --info 參數(shù),能夠直接獲取文件換行符的信息,我們能直接用這個命令來查找和替換。-ic 參數(shù)表示只是打印需要轉(zhuǎn)換的文件。

(MacOS 通過brew 可以安裝 dos2unix version 7.4,而centos 7 和 ubuntu 16 默認只能安裝版本6.0,更高版本需要自己單獨下載安裝包。)

$ dos2unix -i ./roy_test.yml
      11       0       0  no_bom    text    ./roy_test.yml
$ dos2unix -ic ./roy_test.yml
./roy_test.yml

上面的輸出數(shù)字 11 表示有11個dos換行符。

查找并修改dos文件:

$ find . -type f -exec dos2unix -ic {} \; | xargs dos2unix
dos2unix: converting file ./bin/Readme.txt to Unix format...
...

如果文件數(shù)量大,用xargs 替換 exec 更有效率,所以更好的命令是

$ find . -type f | xargs dos2unix -ic | xargs dos2unix

Windows開發(fā)中避免換行問題

使用編輯器Visual Studio Code

這個工具的右下角的文件格式確保是LF。如果不是,就點擊重新選擇。

1567752511438.png

gitbash 中設置默認檢入檢出換行符為linux(\n)風格

(為了團隊更好的協(xié)作)

開啟自動換行
$ git config --global core.autocrlf true

git config --global core.autocrlf true 簽出時將換行符轉(zhuǎn)換成CRLF,簽入時轉(zhuǎn)換回 LF
git config --global core.autocrlf input 簽出時不轉(zhuǎn)換換行符,簽入時轉(zhuǎn)換回 LF
git config --global core.autocrlf false 簽出簽入均不轉(zhuǎn)換

開啟安全換行
$ git config --global core.safecrlf true

解釋:
如果你把換行符搞亂了,在一個文件中既包含windows風格的換行符也包含unix風格換行符,那么 safecrlf 就可以發(fā)揮作用了:
git config --global core.safecrlf true 拒絕提交包含混合換行符的文件
git config --global core.safecrlf false 允許提交包含混合換行符的文件
git config --global core.safecrlf warn 提交包含混合換行符的文件時候給出警示

參考文檔

不同平臺windows、linux、mac 上換行符的問題

vim下unix和dos格式轉(zhuǎn)換

NewLine Wikipedia

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容