在vim裡,要取代換行符號需要找 \n 但是要替換為換行符則是 \r
也就是說
:s/\n/\r/
什麼都不發生。理論上這樣我就已經把所有的\n替換為\r了,然後再找一次的時候
/\r
還是啥都沒,只有
/\n
有值,求原理~~~
我想大声告诉你2017-05-16 16:44:44
我之前寫過一篇筆記,沒有公開,這裡放出來供參考。
(原文是 markdown 格式,SF 並不完全支持,不過不影響閱讀)
筆記正文Vim 中換行符的問題
===============
在 Vim 中如果要使用 s/n/n/g
会导致文件的换行全部被替换成 ^@
字符,按照通常的理解,s/n/n/g
不应该有任何的效果,但在 Vim 中,n
的處理略有不同。
:help NL-used-for-Nul
[<Nul>
](http://vimdoc.sourceforge.net/htmldoc...) characters in the file are stored as [<NL>
](http://vimdoc.sourceforge.net/htmldoc...) in memory. In the display they are shown as "^@
". The translation is done when reading and writing files. To match a [<Nul>
](http://vimdoc.sourceforge.net/htmldoc...) with a search pattern you can just enter [CTRL-@](http://www.vim.org/htmldoc/insert.htm...) or "[CTRL-V](http://www.vim.org/htmldoc/insert.htm...) 000". This is probably just what you expect. Internally the character is replaced with a [<NL>
](http://vimdoc.sourceforge.net/htmldoc...) in the search pattern. What is unusual is that typing [CTRL-V](http://www.vim.org/htmldoc/insert.htm...) [CTRL-J](http://www.vim.org/htmldoc/insert.htm...) also inserts a [<NL>
](http://vimdoc.sourceforge.net/htmldoc...), thus also searches for a [<Nul>
](http://vimdoc.sourceforge.net/htmldoc...) in the file. {Vi cannot handle [<Nul>
](http://vimdoc.sourceforge.net/htmldoc...) characters in the file at all}
從這段說明可以了解到在 Vim 中,空字符 <Nul>
(ASCII 0)在内存中是作为 <NL>
(newline) 進行處理的。
n matches an end-of-line
When matching in a string instead of buffer text a literal newline character is matched.
'n' 在搜尋表達式中是在匹配一個字串,所以字面意義的 'new line' 字串會被匹配到,而不是 <Nul>
字符。在替换表达式中 'n' 会被解释为 <NL>
,于是在内部,<Nul>
会被输入,所以在替换的表达式中 'n' 不再表示 'new line' 或者 'end-of-line'。同样,在搜索表达式中,输入 "CTRL-@" 或者 "CTRL-V 000" 表示 <Nul>
字符,但是在内部,他们还是都被替换为 <NL>
进行处理的,这也就是为什么直接键入 CTRL-V CTRL-J(输入的是 <NL>
字元本身)也有相同的效果的原因。
我想之所以會出現有點混亂的原因可能時 Vi 並不支持 <Nul>
字符,而 Vim 由 Vi 发展而来,作者可能为了方便,直接使用了 <NL>
用来表示 <Nul>
,这也就是 'NL-used-for-Nul' 的字面意思。与此同时,<NL>
原本的作用则使用 <CR>
來替代,這也就是 'CR-used-for-NL' 的字面意思。
:help CR-used-for-NL
When 'fileformat' is "mac",characters in the file are stored as characters internally. In the text they are shown as "^J". Otherwise this works similar to the usage of < NL> for a .
When working with expression evaluation, acharacter in the pattern matches a in the string. The use of "n" (backslash n) to match a < NL> doesn't work there , it only works to match text in the buffer.
那麼,我們如何在替換表達式裡表示 <NL>
呢?答案就是 <CR>
,可以使用 CRTL-V CRTL-M(输入的是 <CR>
字符本身) 或者 'r',Vim 并不会在文件中直接输入 <CR>
字符,它会根据当前 ‘fileformat’ 的设置来决定使用 <CR>
(Mac),<NL>
(*nix) 还是 <CR><NL>
(dos)。
參考資料
--------