3

There seems to be some sort of asymmetry in the way Vim treats ^M when doing string replacement (:s/x/y/).

Perhaps an example is best; say we have this text file:

foo:bar:biz

I want to split this into lines. This works fine:

:s/:/^M/g

(note that ^M is produced by typing Ctrl-V, Enter)

This results in the text file:

foo
bar
baz

Now, if I undo that and try again, I notice that this does not work:

:s/:/\n/g

Here, the resulting text is:

foo^@bar^@biz

That is to say, they are joined by the ASCII NUL byte (0x00).

Question 1: Why does using \n in the replacement result in NUL bytes?

Now, I figure "okay, I guess ^M is used as the 'line separator' character in some way, for Vim; I can work with that".

So I do another experiment, starting with the one-item-per-line text file:

foo
bar
baz

and now, I want to join them with colons, so it looks like the very first incarnation, above.

So I run:

:%s/^M/:/

But this fails, with the error:

E486: Pattern not found: ^M

However, this command does work:

:%s/\n/:/

producing:

foo:bar:biz:

(I can get rid of the trailing colon myself)

So Question 2: Why does \n work in this case, where ^M does not?

And ultimately, Question 3: Why is there this asymmetry between \n and ^M depending on whether it's on the right- or left-hand side of a string replacement command?

jwd
  • 9,860
  • 3
  • 35
  • 59

1 Answers1

3

When searching, \n is a "catch-all" atom that conveniently matches any kind of "end-of-line": CRLF, CR, and LF.

When replacing, \n is <Nul> and represented as ^@.

When replacing, \r is the legal "end-of-line" for the current fileformat.

In short, get used to this pattern and carry on:

:s/\n/\r

See :help NL-used-for-Nul and CR-used-for-NL.

romainl
  • 158,436
  • 18
  • 236
  • 264
  • Thanks for the help links. It looks like the fundamental issue is that the "search" and "replace" portions of `s///` use different syntax, and that's just the way it is. Other help pages for future searchers: `:help sub-replace-special`, `:help pattern`, `:help :s`. For the replacement side, `\r` and `^M` have identical meaning (which the help page indicates with "idem", which I find slightly odd). – jwd Jan 18 '17 at 21:19