How to replace a character by a newline in Vim?

I'm trying to replace each , in the current file by a new line:

:%s/,/n/g 

But it inserts what looks like a ^@ instead of an actual newline. The file is not in DOS mode or anything.

What should I do?

If you are curious, like me, check the question Why is ra newline for Vim? as well.


Use r instead of n .

Substituting by n inserts a null character into the text. To get a newline, use r . When searching for a newline, you'd still use n , however. This asymmetry is due to the fact that n and r do slightly different things:

n matches an end of line (newline), whereas r matches a carriage return. On the other hand, in substitutions n inserts a null character whereas r inserts a newline (more precisely, it's treated as the input <CR>). Here's a small, non-interactive example to illustrate this, using the Vim command line feature (in other words, you can copy and paste the following into a terminal to run it). xxd shows a hexdump of the resulting file.

echo bar > test
(echo 'Before:'; xxd test) > output.txt
vim test '+s/b/n/' '+s/a/r/' +wq
(echo 'After:'; xxd test) >> output.txt
more output.txt
Before:
0000000: 6261 720a                                bar.
After:
0000000: 000a 720a                                ..r.

In other words, n has inserted the byte 0x00 into the text; r has inserted the byte 0x0a.


Here's the trick:

First, set your vi(m) session to allow pattern matching with special characters (ie: newline). It's probably worth putting this line in your .vimrc or .exrc file.

:set magic

Next, do:

:s/,/,^M/g

To get the ^M character, type Control-v and hit Enter. Under Windows, do Control-q, Enter. The only way I can remember these is by remembering how little sense they make:

A: What would be the worst control-character to use to represent a newline?

B: Either q (because it usually means "Quit") or v because it would be so easy to type Control-c by mistake and kill the editor.

A: Make it so.


In the syntax s/foo/bar r and n have different meanings, depending on context.


For foo :
n = newline
r = CR (carriage return = Ctrl-M = ^M)

For bar :
r = is newline
n = null byte (0x00).


I have seen questions on such stuff quite often in the past, and sometime in the future almost noone will know anything about this stuff eventually...

By 'popular' request:

Here is a list of the ASCII control characters, insert them in vim via CTRLvCTRL---key---.
In bash or the other unix/linux shells just type CTRL---key---. Try CTRLM in bash, its the same as hitting ENTER, as the shell realizes what is meant, even though linux systems use Line Feeds for line delimiting. Just the control char for Line Feed is CTRL-A , which is bound to 'jump to beginning of line' in bash.

To insert literal's in bash, CTRLv will also work.

Try in bash:

echo ^[[33;1mcolored.^[[0mnot colored.

This uses ANSI escape sequences, insert the two ^[ 's via CTRLvESC.

You might also try CTRLvCTRLmENTER, which will give you this:

bash: $'r': command not found

Remember the r from above? :>

The ASCII control characters list is different from the standard ascii symbol table, in that the control characters, which are inserted into a console/pseudoterminal/vim via the CTRL key (haha), can be found there. Whereas in C and most other languages you usually use the octal codes to represent these 'characters'.

If you really want to know where all this comes from: http://www.linusakesson.net/programming/tty/.
This is the best link you will come across about this topic, but beware: There be dragons.


TL;DR

Usually foo = n , and bar = r .

链接地址: http://www.djcxy.com/p/1366.html

上一篇: 在Vim中重复整行

下一篇: 如何在Vim中用换行符替换一个字符?