In vim editor, I want to replace a newline character (\n) with two new line characters (\n\n) using vim command mode.

Input file content:

This is my first line.
This is second line.

Command that I tried:

:%s/\n/\n\n/g

it replaces the string with unwanted characters as

This is my first line.^@^@This is second line.^@^@

Then I tried the following command

:%s/\n/\r\r/g

It is working properly. Can you explain me why it is working fine with second command?

Oddly enough, \n in vim for replacement does not mean newline, but null. ASCII nul is ^@ (control@).

Historically, vi replaces ^M (controlM) as the line-ending, which is the newline. vim added an extension \r (like the C language) to mean the same as ^M, but the developers chose to make \n mean null when replacing text. This is inconsistent with its use in searches, which find a newline.

Further reading:

Try this: %s/$/^V^M/ (where ^V is Ctrl-V and ^M is Ctrl-M - when you type ^V it will print a ^ char then backspace over it and then when you type the ^M it will appear as ^M ... the Ctrl-V is the standard tty literal next character - run the command stty -a to show your tty's special chars).

  • Indeed, the very experienced will know this for the ever required conversion from CRLF as an alternative to dropping out and using dos2unix or similar. The Ctrl-V usage is a day 1 vi lesson. – mckenzm Dec 4 '15 at 20:29

vim use \n to represent a null character \0 in memory, that how vim handle file contain null character (while vi can not).

The use of \n only match end of line in the buffer, not the newline in the string when using in expression.

See :h NL-used-for-Null and :h CR-used-for-NL for more details.

Tested with Neovim (nvim) and Vim versions

NVIM v0.3.0
VIM - Vi IMproved 8.1

Remove a newline:

cell
allele
rs2981578
fgfr2

Here, \n matches newlines (to insert a newline however, use \r):

:'<,'>s/\n/|/g

cell|allele|rs2981578|fgfr2

Add a newline:

Nope:

cell|allele|rs2981578|fgfr2

:'<,'>s/\n/|/g

cell^@allele^@rs2981578^@fgfr2

^@ is a diacritic mark for LF (line feed; see http://vimhelp.appspot.com/digraph.txt.html#digraphs-default)

Yes:

cell|allele|rs2981578|fgfr2

:'<,'>s/\r/|/g

cell
allele
rs2981578
fgfr2

To address the OP's question (how to replace one \n with two, \n\n), just add another \r:

cell
allele
rs2981578
fgfr2

:'<,'>s/\n/\r\r/g

cell

allele

rs2981578

fgfr2

... i.e. match the original newline (\n), and replace it with two newlines/carriage returns (\r\r).

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.