如何用Vim中的换行符替换字符?

时间:2020-12-21 20:40:43

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.

但它插入什么看起来像一个^ @而不是一个实际的换行符。该文件不属于DOS模式或任何内容。

What should I do?

我应该做什么?

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

如果你很好奇,就像我一样,问一下为什么\r是Vim的换行符?。

11 个解决方案

#1


2013  

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替换将一个空字符插入到文本中。要得到一条新行,请使用\r。但是,在搜索新行时,仍然使用\n。这种不对称性是由于\n和\r做了稍微不同的事情:

\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.

\n匹配行尾(换行),而\r匹配回车。另一方面,在替代中插入一个null字符,而\r插入一个换行符(更准确地说,它被当作输入 )。这里有一个小的、非交互式的例子来说明这一点,使用Vim命令行特性(换句话说,您可以复制并粘贴到一个终端来运行它)。xxd显示了结果文件的一个hexdump。

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.

换句话说,\n将字节0x00插入到文本中;\r插入了字节0x0a。

#2


162  

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.

首先,设置vi(m)会话,以允许模式匹配特殊字符(例如:newline)。将这一行放到.vimrc或.exrc文件中可能是值得的。

: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:

M ^字符,类型- v和回车。在Windows下,执行Control-q,输入。我能记住这些的唯一方法是记住它们的意义:

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

A:用来表示换行的最坏的控制字符是什么?

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.

B: q(因为它通常意味着“退出”)或v,因为它很容易在错误中键入Control-c,并杀死编辑器。

A: Make it so.

答:让它如此。

#3


60  

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

根据上下文,在语法s/foo/bar \r和\n中有不同的含义。


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

为foo:\ n =换行符\ r = CR(回车= Ctrl-M = ^)

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

对于bar: \r =是newline \n = null字节(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.

这里是一个ASCII控制字符列表,将它们插入vim中,通过ctrl + ctrl ---key---。在bash或其他unix/linux shell中,只需按CTRL---键---。在bash中尝试使用ctrl lm,它与按回车键相同,因为shell实现了什么意思,即使linux系统使用换行符来限制行。仅用于行提要的控制字符是CTRL-A,在bash中绑定到“跳转到行开始”。

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

若要在bash中插入文字,则ctrl lv也可以工作。

Try in bash:

试着在bash中:

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

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

这将使用ANSI转义序列,将这两个参数插入。

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

您还可以尝试使用ctrl - ctrl - lmenter,它将给您这样的:

bash: $'\r': command not found

Remember the \r from above? :>

还记得上面的\r吗?:>

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'.

ASCII控制字符列表与标准的ASCII符号表不同,在这个表中,通过CTRL键(haha)将控制字符插入到控制台/伪终端/vim中,可以在那里找到。而在C语言和其他大多数语言中,你通常使用八进制码来表示这些“字符”。

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.

如果你真的想知道这些信息来自哪里:http://www.linusakesson.net/programming/tty/。这是你将会遇到的关于这个话题的最好的链接,但是要注意:有龙。


TL;DR

博士TL;

Usually foo = \n, and bar = \r.

通常是foo = \n,和bar = \r。

#4


41  

You need to use

您需要使用

:%s/,/^M/g

To get the ^M character, press Ctrl v followed by Enter

M ^字符,按Ctrl v输入紧随其后

#5


27  

\r can do the work here for you.

你可以在这里为你做这项工作。

#6


20  

With Vim on Windows use Ctrl+Q in place of Ctrl+V

有Vim在Windows上使用Ctrl+Q代替Ctrl+V。

#7


8  

From eclipse, the ^M characters can be embedded in a line, and you want to convert them to newlines.

从eclipse,M ^字符可以嵌在一条线,你想将它们转换为换行。

:s/\r/\r/g

#8


5  

But if one has to substitute then following thing works

但是如果一个人必须替代,那么接下来的事情就会发生。

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

in the above every next line is substituted with next line and then |- and again a next line. This is used in wiki tables. if the text is as follows:

在上面的每一行中,下一行被替换,然后是|,再下一行。这在wiki表中使用。如果案文如下:

line1
line2
line3

is changed to

更改为

line1
|-
line2
|-
line3

#9


5  

This is the best answer for the way I think but it would have been nicer in a table: https://*.com/a/12389839/962394.

这是我认为最好的答案,但它在表格中会更好:https://*.com/a/12389839/962394。

So, rewording:

所以,说辞:

You need to use \r to use a line feed (ascii 0x0a, the unix newline) in a regex replacement but that is peculiar to the replacement - you should normally continue to expect to use \n for line feed and \r for carriage return.

您需要使用\r在regex替换中使用一个行馈线(ascii 0x0a, unix换行),但这是替换的特殊情况—您应该正常地继续期望使用\n来进行换行,并使用\r作为回车。

This is because vim used \n in a replacement to mean the NIL character (ascii 0x00). You might have expected NIL to have been \0 instead, freeing \n for its usual use for line feed, but \0 already has a meaning in regex replacements so it was shifted to \n. Hence then going further to also shift the newline from \n to \r (which in a regex pattern is the carriage return character, ascii 0x0d).

这是因为vim在替换中使用\n,以表示NIL字符(ascii 0x00)。您可能会认为NIL已经是\0了,但是,对于它通常用于换行的使用,它已经释放了,但是\0已经在regex替换中有了意义,所以它被转移到\n。因此,进一步将换行符从\n改为\r(在regex模式中是回车字符ascii 0x0d)。

character                | ascii code | C representation | regex match | regex replacement
-------------------------+------------+------------------+-------------+------------------------
nil                      | 0x00       | \0               | \0          | \n
line feed (unix newline) | 0x0a       | \n               | \n          | \r
carriage return          | 0x0d       | \r               | \r          | <unknown>

NB: ^M (Ctrl-V Ctrl-M on linux) inserts a newline when used in a regex replacement rather than a carriage return as others have advised (I just tried it).

注:^ M(ctrl - v Ctrl-M linux)中使用一个正则表达式替换时插入一个新行,而不是一个回车,其他人则建议(我试过)。

Also note that vim will translate the line feed character when it saves to file based on its file format settings and that might confuse matters.

还要注意的是,vim将根据其文件格式设置将行提要字符转换为文件,这可能会混淆问题。

#10


4  

If you need to do for a whole file, it was also suggested to me that you could try from the command line

如果您需要对整个文件进行处理,还可以向我建议您可以尝试从命令行尝试。

sed 's/\\n/\n/g' file > newfile

#11


2  

Heres the answer that worked for me. From this guy

这就是我的答案。从这个家伙

----quoting http://jaysonlorenzen.wordpress.com/2009/04/28/use-vi-editor-to-insert-newline-char-in-replace/

——引用http://jaysonlorenzen.wordpress.com/2009/04/28/use-vi-editor-to-insert-newline-char-in-replace/


Something else I have to do and cannot remember and then have to look up.

有些事我必须做,不能记住,然后必须向上看。

In vi to insert a newline character in a search and replace, do the following:

在vi中插入换行字符,在搜索和替换中,执行以下操作:

:%s/look_for/replace_with^M/g the command above would replace all instances of “look_for” with “replace_with\n” (with \n meaning newline)

:% s / look_for / replace_with ^ M / g以上命令将取代所有实例的“look_for”与“replace_with \ n”换行符(\ n意义)

to get the “^M”, enter the key combination “ctl-V” then after that (release all keys) press the “enter” key.

“^”,进入组合键“ctl-V”之后(释放所有键)按“输入”键。


#1


2013  

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替换将一个空字符插入到文本中。要得到一条新行,请使用\r。但是,在搜索新行时,仍然使用\n。这种不对称性是由于\n和\r做了稍微不同的事情:

\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.

\n匹配行尾(换行),而\r匹配回车。另一方面,在替代中插入一个null字符,而\r插入一个换行符(更准确地说,它被当作输入 )。这里有一个小的、非交互式的例子来说明这一点,使用Vim命令行特性(换句话说,您可以复制并粘贴到一个终端来运行它)。xxd显示了结果文件的一个hexdump。

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.

换句话说,\n将字节0x00插入到文本中;\r插入了字节0x0a。

#2


162  

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.

首先,设置vi(m)会话,以允许模式匹配特殊字符(例如:newline)。将这一行放到.vimrc或.exrc文件中可能是值得的。

: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:

M ^字符,类型- v和回车。在Windows下,执行Control-q,输入。我能记住这些的唯一方法是记住它们的意义:

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

A:用来表示换行的最坏的控制字符是什么?

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.

B: q(因为它通常意味着“退出”)或v,因为它很容易在错误中键入Control-c,并杀死编辑器。

A: Make it so.

答:让它如此。

#3


60  

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

根据上下文,在语法s/foo/bar \r和\n中有不同的含义。


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

为foo:\ n =换行符\ r = CR(回车= Ctrl-M = ^)

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

对于bar: \r =是newline \n = null字节(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.

这里是一个ASCII控制字符列表,将它们插入vim中,通过ctrl + ctrl ---key---。在bash或其他unix/linux shell中,只需按CTRL---键---。在bash中尝试使用ctrl lm,它与按回车键相同,因为shell实现了什么意思,即使linux系统使用换行符来限制行。仅用于行提要的控制字符是CTRL-A,在bash中绑定到“跳转到行开始”。

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

若要在bash中插入文字,则ctrl lv也可以工作。

Try in bash:

试着在bash中:

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

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

这将使用ANSI转义序列,将这两个参数插入。

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

您还可以尝试使用ctrl - ctrl - lmenter,它将给您这样的:

bash: $'\r': command not found

Remember the \r from above? :>

还记得上面的\r吗?:>

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'.

ASCII控制字符列表与标准的ASCII符号表不同,在这个表中,通过CTRL键(haha)将控制字符插入到控制台/伪终端/vim中,可以在那里找到。而在C语言和其他大多数语言中,你通常使用八进制码来表示这些“字符”。

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.

如果你真的想知道这些信息来自哪里:http://www.linusakesson.net/programming/tty/。这是你将会遇到的关于这个话题的最好的链接,但是要注意:有龙。


TL;DR

博士TL;

Usually foo = \n, and bar = \r.

通常是foo = \n,和bar = \r。

#4


41  

You need to use

您需要使用

:%s/,/^M/g

To get the ^M character, press Ctrl v followed by Enter

M ^字符,按Ctrl v输入紧随其后

#5


27  

\r can do the work here for you.

你可以在这里为你做这项工作。

#6


20  

With Vim on Windows use Ctrl+Q in place of Ctrl+V

有Vim在Windows上使用Ctrl+Q代替Ctrl+V。

#7


8  

From eclipse, the ^M characters can be embedded in a line, and you want to convert them to newlines.

从eclipse,M ^字符可以嵌在一条线,你想将它们转换为换行。

:s/\r/\r/g

#8


5  

But if one has to substitute then following thing works

但是如果一个人必须替代,那么接下来的事情就会发生。

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

in the above every next line is substituted with next line and then |- and again a next line. This is used in wiki tables. if the text is as follows:

在上面的每一行中,下一行被替换,然后是|,再下一行。这在wiki表中使用。如果案文如下:

line1
line2
line3

is changed to

更改为

line1
|-
line2
|-
line3

#9


5  

This is the best answer for the way I think but it would have been nicer in a table: https://*.com/a/12389839/962394.

这是我认为最好的答案,但它在表格中会更好:https://*.com/a/12389839/962394。

So, rewording:

所以,说辞:

You need to use \r to use a line feed (ascii 0x0a, the unix newline) in a regex replacement but that is peculiar to the replacement - you should normally continue to expect to use \n for line feed and \r for carriage return.

您需要使用\r在regex替换中使用一个行馈线(ascii 0x0a, unix换行),但这是替换的特殊情况—您应该正常地继续期望使用\n来进行换行,并使用\r作为回车。

This is because vim used \n in a replacement to mean the NIL character (ascii 0x00). You might have expected NIL to have been \0 instead, freeing \n for its usual use for line feed, but \0 already has a meaning in regex replacements so it was shifted to \n. Hence then going further to also shift the newline from \n to \r (which in a regex pattern is the carriage return character, ascii 0x0d).

这是因为vim在替换中使用\n,以表示NIL字符(ascii 0x00)。您可能会认为NIL已经是\0了,但是,对于它通常用于换行的使用,它已经释放了,但是\0已经在regex替换中有了意义,所以它被转移到\n。因此,进一步将换行符从\n改为\r(在regex模式中是回车字符ascii 0x0d)。

character                | ascii code | C representation | regex match | regex replacement
-------------------------+------------+------------------+-------------+------------------------
nil                      | 0x00       | \0               | \0          | \n
line feed (unix newline) | 0x0a       | \n               | \n          | \r
carriage return          | 0x0d       | \r               | \r          | <unknown>

NB: ^M (Ctrl-V Ctrl-M on linux) inserts a newline when used in a regex replacement rather than a carriage return as others have advised (I just tried it).

注:^ M(ctrl - v Ctrl-M linux)中使用一个正则表达式替换时插入一个新行,而不是一个回车,其他人则建议(我试过)。

Also note that vim will translate the line feed character when it saves to file based on its file format settings and that might confuse matters.

还要注意的是,vim将根据其文件格式设置将行提要字符转换为文件,这可能会混淆问题。

#10


4  

If you need to do for a whole file, it was also suggested to me that you could try from the command line

如果您需要对整个文件进行处理,还可以向我建议您可以尝试从命令行尝试。

sed 's/\\n/\n/g' file > newfile

#11


2  

Heres the answer that worked for me. From this guy

这就是我的答案。从这个家伙

----quoting http://jaysonlorenzen.wordpress.com/2009/04/28/use-vi-editor-to-insert-newline-char-in-replace/

——引用http://jaysonlorenzen.wordpress.com/2009/04/28/use-vi-editor-to-insert-newline-char-in-replace/


Something else I have to do and cannot remember and then have to look up.

有些事我必须做,不能记住,然后必须向上看。

In vi to insert a newline character in a search and replace, do the following:

在vi中插入换行字符,在搜索和替换中,执行以下操作:

:%s/look_for/replace_with^M/g the command above would replace all instances of “look_for” with “replace_with\n” (with \n meaning newline)

:% s / look_for / replace_with ^ M / g以上命令将取代所有实例的“look_for”与“replace_with \ n”换行符(\ n意义)

to get the “^M”, enter the key combination “ctl-V” then after that (release all keys) press the “enter” key.

“^”,进入组合键“ctl-V”之后(释放所有键)按“输入”键。