如何在Vim中用换行符替换字符

我正在尝试用新行替换当前文件中的每个,

:%s/,/\n/g

但它插入了看起来像^@而不是实际的换行符的内容。该文件不在DOS模式或任何东西中。

我该怎么办?

如果你像我一样好奇,也检查问题为什么\r是Vim的换行符?

980367 次浏览

使用\r而不是\n

\n替换会在文本中插入一个空字符。要获得换行符,请使用\r。然而,当搜索作为换行符时,您仍然会使用\n。这种不对称是由于\n\r做稍微不同的事情

\n匹配行尾(换行符),而\r匹配回车。另一方面,在替换中,\n插入空字符,而\r插入换行符(更准确地说,它被视为输入CR)。这里有一个小的非交互式示例来说明这一点,使用Vim命令行功能(换句话说,您可以将以下内容复制并粘贴到终端中以运行它)。xxd显示了结果文件的hexuck。

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

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

\r可以在这里为你做工作。

您需要使用:

:%s/,/^M/g

要获取^M字符,请按Ctrl+v,然后按输入

使用Windows上的Vim,使用Ctrl+Q代替Ctrl+V

这就是诀窍:

首先,设置您的Vi(m)会话以允许使用特殊字符进行模式匹配(即:换行符)。可能值得将这一行放在您的. vimrc或. exrc文件中:

:set magic

接下来,做:

:s/,/,^M/g

要获取^M字符,请键入Ctrl+V并点击输入。在Windows下,执行Ctrl+Q输入。我能记住这些的唯一方法是记住它们的意义有多小:

答:用什么最差的控制字符来表示换行符?

B:#0(因为它通常意味着“退出”)或#1,因为很容易错误地键入Ctrl+C并杀死编辑器。

答:让它如此。

Eclipse开始,^M字符可以嵌入到一行中,并且您希望将它们转换为换行符。

:s/\r/\r/g

这是对我有用的答案。来自这个人:

引用使用vi编辑器在替换中插入换行符


还有一些我必须做的事情,不记得了,然后不得不抬头看。

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

:%s/look_for/replace_with^M/g

上面的命令会将“look_for”的所有实例替换为“replace_with\n”(\n表示换行符)。

要获得“^M”,请输入组合键Ctrl+V,然后(释放所有键)按输入键。


但如果必须替换,那么以下方法有效:

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

在上面,每一行都被下一行替换,然后|-和一个新行。这在wiki表中使用。

如果案文如下:

line1line2line3

它被改为

line1|-line2|-line3

如果您需要为整个文件执行此操作,我还建议您可以从命令行尝试:

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

在语法s/foo/bar中,\r\n具有不同的含义,具体取决于上下文。


短:

对于foo

\r=="回车"(CR/^M
\n==在Linux /Mac上匹配换行符(LF),在Windows上匹配CRLF

对于bar

\r==在Linux /Mac上产生LF,在Windows上产生CRLF
\n=="空字节"(NUL/^@

当在linux(即在网络服务器上)编辑最初在windows环境中创建并上传(即FTP/SFTP)的文件时-您在vim中看到的所有^M都是CR,linux不翻译,因为它仅使用LF来描述换行符。


较长(含ASCII码):

NUL==0x00==0==Ctrl+@==^@如vim
所示LF==0x0A==10==Ctrl+J
CR==0x0D==13==Ctrl+M==^M如vim

这是ASCII控制字符的列表。通过Ctrl+VCtrl+---钥匙---将它们插入Vim中。

在Bash或其他Unix/Linuxshell中,只需键入Ctrl+---钥匙---

在Bash中尝试Ctrl+M。这与点击输入相同,因为shell意识到这意味着什么,即使Linux系统使用换行符进行行定界。

要在bash中插入文字,在它们前面加上Ctrl+V也可以。

试试Bash:

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

这使用ANSI转义序列。通过Ctrl+VEsc插入两个^[

您也可以尝试Ctrl+VCtrl+M输入,这将为您提供:

bash: $'\r': command not found

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

这个ASCII控制字符列表不同于完整的ASCII符号表,因为控制字符通过Ctrl键插入到控制台/伪终端/Vim中(哈哈),可以在那里找到。

而在C和大多数其他语言中,您通常使用八进制代码来表示这些“字符”。

如果你真的想知道这一切是从哪里来的:TTY揭开了神秘面纱。这是你在这个话题上遇到的最好的链接,但要小心:有龙。


太长别读

通常foo=\nbar=\r

这是我思考方式的最佳答案,但放在桌子上会更好:

为什么\r是Vim的换行符?

所以,重新措辞:

您需要使用\r在regex替换中使用换行符(ASCII0x0A,Unix换行符),但这是替换所特有的-您通常应该继续期望使用\n换行符和\r回车。

这是因为Vim在替换中使用了\n来表示NIL字符(ASCII0x00)。您可能期望NIL是\0,从而将\n释放出来用于换行符,但\0在正则表达式替换中已经有了意义,因此它被转移到\n。因此,进一步将换行符从\n转移到\r(在正则表达式模式中是回车字符,ASCII0x0D)。

Character                | ASCII code | C representation | Regex match | Regex replacement-------------------------+------------+------------------+-------------+------------------------nil                      | 0x00       | \0               | \0          | \nline feed (Unix newline) | 0x0a       | \n               | \n          | \rcarriage return          | 0x0d       | \r               | \r          | <unknown>

注意:^M(Linux上的Ctrl+VCtrl+M)在正则表达式替换中使用时插入换行符,而不是像其他人建议的那样回车(我刚刚尝试过)。

另请注意,Vim将在根据其文件格式设置保存到文件时转换换行符,这可能会混淆问题。

在vim编辑器中,以下命令成功地将\n替换为新行

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