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

Vin*_*vic 1870 vi vim replace newline escaping

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

:%s/,/\n/g 
Run Code Online (Sandbox Code Playgroud)

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

我该怎么办?

如果你像我一样好奇,请检查问题为什么\ raim的换行?同样.

Kon*_*lph 2449

\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
Run Code Online (Sandbox Code Playgroud)
Before:
0000000: 6261 720a                                bar.
After:
0000000: 000a 720a                                ..r.
Run Code Online (Sandbox Code Playgroud)

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

  • / r被视为按Enter/Return键.它适用于所有平台. (120认同)
  • 另请参阅[为什么\ raim的换行符?](http://stackoverflow.com/questions/71417/why-is-ra-newline-for-vim). (72认同)
  • 我希望这适用于经典的vi.在AIX v6.1上,`\ r`不能像这样工作.但你可以按`Ctrl-V``Enter`代替输入`\ r``,它可以工作. (13认同)
  • @SunnyRaj 你确定 CR 和 LF 的历史吗?我的印象是,最初 LF 将纸张向前移动一排但没有移动打印头,而 CR 移动了打印头但没有移动纸张。因此,如果您的操作系统在打印前没有转换输入,您就不能只使用 LF 或 CR 来获得正确的输出。MS DOS 使用原始打印机数据作为文本文件格式,Mac OS 使用 CR 并将其转换为打印机的原始格式,而 UNIX 使用 LF 并将其转换为打印机的原始格式。 (4认同)
  • 我迟到了.如果`\ r``插入`<CR>`并且`\n`插入一个null,我怎么用回车替换一些东西? (3认同)
  • 我有一个很长的行,其中包含很多显式的“\n”,我想将它们分别扩展为一行。读完这个帖子后,`%s/\\n/\r/g` 成功了!(注意额外的 \,否则它会搜索实际的换行符) (2认同)

Log*_*gan 200

这是诀窍:

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

:set magic
Run Code Online (Sandbox Code Playgroud)

接下来,做:

:s/,/,^M/g
Run Code Online (Sandbox Code Playgroud)

要获取^M角色,请键入Control- v并点击Enter.在Windows下,做Control- q, Enter. 我记住这些的唯一方法就是记住它们的意义不大:

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

B:要么q(因为它通常意味着"退出"),要么v因为它很容易打字Control- c错误地杀了编辑器.

答:这样做.

  • Ctrl-v是"逐字"的助记符 - 即将下一个键按下到"逐字"键码/字符.在Windows中粘贴:保持熟悉.Ctrl-Q可能是"(un)引用".相当愚蠢 - 但你可以在二进制文件中使用它 - 例如通过Ctrl-Z搜索Ctrl-A(我猜是Ascii 1-26). (26认同)
  • 我在Windows上使用GVim,我既不需要`:set magic`(它不在我的〜/ _vimrc中)或`ctrl-q`.只需一个简单的`ctrl-v`然后输入就可以为我创建`^ M`字符就好了. (8认同)
  • Cv不代表换行符; 它是"逃避下一个文字字符"命令.我不知道Cv是什么的助记符,但是有一个原因它没有精神上映射到换行符. (5认同)

sja*_*jas 92

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


短:

对于foo:
\n =换行符(linux/mac上为LF,Windows上为CRLF)
\ r \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n

对于bar:
\ r =是换行符
\n =空字节.

更长:(用ascii数字)

NUL= 0x00 = 0 = CTRL@
LF= 0x0A = 10 = CTRLJ
CR= 0x0D = 13 =CTRLM

这是ASCII控制字符列表,将它们插入^[via CTRLvCTRL---key---.
\r或其他unix/linux shell中输入CTRL---key---.尽管linux系统使用Line Feeds进行行分隔,但尝试CTRLM使用bash,它与命中相同ENTER,因为shell实现了意义.

要在bash中插入文字,可以使用它们CTRLv.

尝试bash:

echo ^[[33;1mcolored.^[[0mnot colored.
Run Code Online (Sandbox Code Playgroud)

这使用ANSI转义序列,插入两个foo的via CTRLvESC.

你也可以试试CTRLvCTRLmENTER,这会给你这个:

bash: $'\r': command not found
Run Code Online (Sandbox Code Playgroud)

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

这个ASCII控制字符列表与完整的ASCII符号表不同,因为CTRL可以在那里找到通过密钥(haha)插入控制台/伪终端/ vim的控制字符.在C和大多数其他语言中,您通常使用八进制代码来表示这些"字符".

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


TL; DR

通常bar= \r,和s/foo/bar= \r.

  • 谢谢sjas,你知道这个问题是有史以来最奇怪的问题之一.1008票的答案基本上只是说"vim做了你发现的东西.那是因为vim做了你发现的东西.永远不要忘记vim做了你找到的东西." 我希望找到一个代码清单,列出模式中的有趣角色,替换和古怪的原因,因此它易于记忆和预测其他类似的怪异.那会得到我的投票. (3认同)
  • @codeshot`:s / x / ^ M / g`应该可以。通过`ctrl-v`插入`^ M`,然后插入`ctrl-m`。 (2认同)

dog*_*ane 51

你需要使用

:%s/,/^M/g
Run Code Online (Sandbox Code Playgroud)

要获得^M角色,请按,Ctrl v然后按Enter

  • 我必须做<Cv> <Cm>来获得^ M字符. (4认同)

Las*_*sar 37

\r 可以为你做这个工作.


gra*_*ntc 24

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


ric*_*usa 11

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

:s/\r/\r/g
Run Code Online (Sandbox Code Playgroud)


cod*_*hot 11

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

所以,重写:

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

这是因为\n在替换中使用的vim 意味着NIL字符(ascii 0x00).您可能已经预料到NIL会被\0替换,\n因为它通常用于换行,但\0已经在正则表达式替换中具有意义,因此它已转移到\n.因此,然后进一步将换行符转换\n\r(在正则表达式模式中是回车符,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>

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

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


Kir*_*nta 8

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

:%s/\n/\r\|\-\r/g
Run Code Online (Sandbox Code Playgroud)

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

line1
line2
line3
Run Code Online (Sandbox Code Playgroud)

改为

line1
|-
line2
|-
line3
Run Code Online (Sandbox Code Playgroud)


Eva*_*van 7

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

sed 's/\\n/\n/g' file > newfile
Run Code Online (Sandbox Code Playgroud)


小智 5

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

---- quoting 使用vi编辑器在replace中插入换行符


我必须做的其他事情,无法记住,然后必须查找。

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

:%s/look_for/replace_with^M/g
Run Code Online (Sandbox Code Playgroud)

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

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