問題背景
VIM在打開文件的時候如果遇到兩種換行符風格(dos與unix)共存的文件,通常會在行尾顯示出煩人的^M。如果^M較少,比較容易定位到哪幾行出了問題,但是如果^M較多,就很難搞。下面先給出解法,再來做分析。
解決方案
- ^M較少,需要定位哪幾行包含^M,只需要在vim中輸入:
/\r
- ^M較多,需要定位到哪幾行不包含^M,只需要在vim中輸入:
/^\(.*\r\)\@!.*
原理解析
要了解如何定位^M,首先得知道^M是如何產生的。要了解^M的產生原因,首先得了解VIM的fileformat——文件換行符風格。
- 三種換行符風格
換行符風格目前分了三種風格,分別是:
- DOS-format:采用\r\n換行,在vim中用"dos"表示,Windows系統默認風格
- unix-format:采用\n換行,在vim中用"unix"表示,unix派系系統默認風格
- Mac-format:采用\r換行,在vim中用"mac"表示,Mac系統默認風格
想確定當前文件是被vim判斷為哪種文件格式,可以在vim內輸入“:set fileformat”,如果是unix風格,會在左下角的命令輸入行顯示如下:
另外還可以用":set fileformats"查看當前配置的vim支持哪些換行符風格,如果能確定當前文件的格式不在可識別文件格式列表內,可以使用":set fileformats=unix,dos,mac"手動添加可識別格式。
三種風格的歷史由來感興趣的同學可以自行百度,還是挺有意思的。
- vim是如何判斷文件的fileformat的
- 如果所有行都是以 "\r\n" 也就是<CR><NL>結尾,'fileformat' 會被設置為 "dos"
- 如果 "fileformats" 包含 "mac" 並且文件不含 "\r" 也就是 <NL> 字符,'fileformat' 會被設置為 "mac"
- 以上兩種情況之外的,會設置為 ‘unix’
- ^M是如何產生的
因為只有當文件所有行都是以 "\r\n" 結尾,能被識別為 "dos" 格式,所有當文件內 "\r\n" 風格和 "\n" 風格共存的時候,就會被標志為 "unix" 風格,而在unix風格中,只有 "\n" 被識別為換行,多余的 "\r" 就會用^M標識出來,^M其實就是 "\r" 在vim中的字符表述。所以在上文中用 "\r" 作為匹配字符串的時候,會匹配到 ^M,如下圖所示
- 匹配不包含^M的行
匹配包含某個字符串的行非常的簡單,但是匹配不包含某個字符串的行,就需要花費一番功夫了。具體可以參考這篇博文: http://blog.sina.com.cn/s/blog_9eccc8e50102wd7h.html。博主也是參考了這篇博文之后,才摸索出了上面的匹配不存在^M的行的寫法。
總結
本次最大的收獲是從原理上理解了vim是如何判斷文件換行符風格的,在了解了原理之后,才能更清晰的認識到^M產生的原因,並且輕松找到應對方案。另外也掌握了vim里面匹配不存在行的技巧,這是一個非常有用的技巧。