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


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

:%s/,/\n/g 

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

我该怎么办?

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


1591
2017-09-16 11:19


起源


Stack Overflow是一个编程和开发问题的站点。这个问题似乎是偏离主题的,因为它不是关于编程或开发。看到 我在这里可以问什么主题 在帮助中心。也许 超级用户 要么 Unix和Linux堆栈交换 会是一个更好的地方。 - jww
@jww这个问题是10岁......似乎太老了,无法迁移。有很多这样的问题,例如: stackoverflow.com/questions/10175812/... - Vinko Vrsalovic


答案:


使用 \r 代替 \n

代替 \n 在文本中插入空字符。要获得换行符,请使用 \r。什么时候 搜索 对于换行,你仍然会使用 \n但是。这种不对称是由于这一事实 \n 和 \r  做稍微不同的事情

\n 匹配行尾(换行符),而 \r 匹配回车。另一方面,在替换中 \n 插入一个空字符,而 \r 插入换行符(更准确地说,它被视为输入 <CR>)。这是一个小的非交互式示例,使用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.

换一种说法, \n 已将字节0x00插入文本中; \r 已插入字节0x0a。


2076
2017-09-16 11:21



为什么这样做? - Vinko Vrsalovic
/ r被视为按Enter / Return键。它适用于所有平台。 - Luka Marinko
无论出于何种原因,将所有'\ n替换为',\ n在执行时有效:%s /'\ n /',\ r / g - tipu
也可以看看 为什么\ r \ n是Vim的换行符?。 - Andrew Marshall
我希望这适用于经典的vi。在AIX v6.1上, \r 不像这样工作。但你可以按 Ctrl-V  Enter 代替打字 \r,它的工作原理。 - eksortso


这是诀窍:

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

:set magic

接下来,做:

:s/,/,^M/g

得到的 ^M 字符,类型 控制 - v 并击中 输入。在Windows下,做 控制 - q输入。我能记住这些的唯一方法就是记住它们的意义:

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

B: q (因为它通常意味着“退出”)或 v 因为它很容易输入 控制 - C 错误地杀了编辑器。

A: 这样做。


166
2017-09-25 23:40



我在Windows上使用GVim,我不需要 :set magic (它不在我的〜/ _vimrc中)或 ctrl-q。只是一个简单的 ctrl-v 然后输入创建 ^M 我的性格很好。 - Chris Phillips
C-v不代表换行符;它是“逃避下一个字面字符”命令。我不知道C-v是什么的助记符,但有一个原因它没有精神上映射到换行符。 - Jim Stewart
Ctrl-v是“逐字”的助记符 - 即将下一个键按下到其“逐字”键码/字符。在Windows中它是粘贴:保持熟悉。 Ctrl-Q可能是“(un)引用”。相当愚蠢 - 但你可以在二进制文件中使用它 - 例如通过Ctrl-Z搜索Ctrl-A(我猜是Ascii 1-26)。 - Tomasz Gandor
现在我必须删除额外的“,”这个命令介绍... - Danny Wang
Ctrl-C 实际上并没有杀死编辑器,虽然它可以取消你回到普通模式。 Ctrl-V 意思是逐字,和 Ctrl-Q 意味着有人犯了加载错误的错误 $VIMRUNTIME/mswin.vim 配置文件。你不需要mswin。只需使用自己的vimrc即可。 - 00dani


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


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

对于 bar
\ r =是换行符
\ n =空字节(0x00)。


过去我经常看到有关这类东西的问题,将来的某个时候几乎没有人会对这些东西有所了解......

按'受欢迎'的要求:

这是一份清单 ASCII控制字符,插入它们 vim 通过 CTRLvCTRL - -键 - -
bash 或者其他unix / linux shell只需输入 CTRL - -键 - -。尝试 CTRL中号 在bash中,它与击中相同 输入,即使linux系统使用Line Feeds进行行分隔,shell也意味着它意味着什么。只是换行的控件字符是 CTRL-A,这必然会在bash中“跳到行首”。

要在bash中插入文字, CTRLv 也会工作。

尝试bash:

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

这用了 ANSI转义序列,插入两个 ^[通过 CTRLv退出

你也可以试试 CTRLvCTRL输入,这会给你这个:

bash: $'\r': command not found

记得 \r 从上面? :>

ASCII控制字符 列表与标准不同 ascii符号表,在控制字符,通过的插入控制台/ pseudoterminal / vim CTRL 钥匙(哈哈),可以在那里找到。 而在C和大多数其他语言中,您通常使用八进制代码来表示这些“字符”。

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


TL; DR

平时 foo = \n,和 bar = \r


65
2017-09-23 14:00



所以我很想知道如何用回车代替一个角色 - codeshot
@codeshot :s/x/^M/g 应该做。插入 ^M 通过 ctrl-v 其次是 ctrl-m。 - sjas
谢谢sjas,你知道这个问题是有史以来最奇怪的问题之一。 1008票的回答基本上只是说“vim做了你发现的东西。那是因为vim做你发现的东西。永远不要忘记vim做了你找到的东西。”我希望找到一个代码清单,列出模式中有趣的角色,替换和古怪的原因,因此它易于记忆和预测其他类似的怪异。那会得到我的投票。 - codeshot
@codeshot一个ascii控制字符列表可能会帮助你。看到 cs.tut.fi/~jkorpela/chars/c0.html 供进一步参考。我将更新我的答案,包括两个链接。 - sjas
@codeshot我用你可能觉得有趣的东西再次更新了帖子。由于HARD通过谷歌在一个连贯的文章中找到这方面的信息,我想这些东西的博客文章已经过期...... - sjas


你需要使用

:%s/,/^M/g

得到的 ^M 性格,按 按Ctrl  v 其次是 输入


45
2017-09-16 11:30



我必须做<C-v> <C-m>来获得^ M字符。 - Jezen Thomas


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


27
2017-09-16 11:21





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


20
2017-09-16 11:45





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

:s/\r/\r/g

8
2017-09-06 17:53





但是,如果必须替代,那么下面的事情是有效的

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

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

line1
line2
line3

改为

line1
|-
line2
|-
line3

5
2018-02-07 08:09





这是我想的方式的最佳答案,但它在表格中会更好: https://stackoverflow.com/a/12389839/962394

所以,重写:

你需要使用 \r 使用换行符(ascii 0x0a,unix换行符)在正则表达式替换中,但这是替换所特有的 - 你通常应该继续期望使用 \n 换行和 \r 回车。

这是因为使用了vim \n 替换为NIL字符(ascii 0x00)。你可能已经预料到NIL了 \0 相反,释放 \n 它通常用于换行,但是 \0 已经在正则表达式替换中有意义所以它被转移到了 \n。因此,进一步转移新线 \n 至 \r (在正则表达式模式中是回车符,ascii 0x0d)。

人物| ascii代码| C表示|正则表达式匹配|正则表达式替换
------------------------- + ------------ + ----------- ------- + ------------- + ------------------------
无| 0x00 | \ 0 | \ 0 | \ n
换行(unix换行符)| 0x0a | \ n | \ n | \ r
回车| 0x0d | \ r | \ r | <未知>

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

另请注意,当vim根据文件格式设置保存到文件时,它会转换换行符,这可能会使事情变得混乱。


5
2018-04-08 12:15





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

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

4
2018-02-09 23:01



请注意,这需要GNU sed。尝试 printf 'foo\\nbar\n' | sed 's/\\n/\n/g' 看看它是否适用于您的系统。 (感谢freenode上#bash的优秀人士提出此建议。) - Evan Donovan


这是对我有用的答案。从这个家伙

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


我必须做的其他事情,不记得,然后必须抬头。

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

:%S / look_for / replace_with ^ M /克 上面的命令将用“replace_with \ n”替换“look_for”的所有实例(\ n表示换行符)

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



2
2018-02-03 19:31