如何在 Vim 中用换行符替换字符
Posted
技术标签:
【中文标题】如何在 Vim 中用换行符替换字符【英文标题】:How to replace a character by a newline in Vim 【发布时间】:2010-09-09 10:29:15 【问题描述】:我正在尝试用新行替换当前文件中的每个 ,
:
:%s/,/\n/g
但它会插入看起来像 ^@
的东西,而不是实际的换行符。该文件不在 DOS 模式下。
我该怎么办?
如果你和我一样好奇,也可以查看问题Why is \r a newline for Vim?。
【问题讨论】:
Stack Overflow 是一个编程和开发问题的网站。这个问题似乎离题了,因为它与编程或开发无关。请参阅帮助中心的What topics can I ask about here。也许Super User 或Unix & Linux Stack Exchange 会是一个更好的提问地点。 @jww 这个问题已有 10 年历史了......似乎太老了,无法迁移。有很多这样的问题,例如:***.com/questions/10175812/… @jww vim是程序员常用的工具,程序员常用工具的问题在Stack Overflow的话题。虽然显然这更适合Vi and Vim。 【参考方案1】:使用\r
而不是\n
。
替换为\n
会在文本中插入一个空字符。要获得换行符,请使用\r
。但是,当搜索换行时,您仍然会使用\n
。这种不对称是由于\n
和\r
do slightly different things:
\n
匹配行尾(换行符),而\r
匹配回车符。另一方面,在替换中\n
插入一个空字符,而\r
插入一个换行符(更准确地说,它被视为输入CR)。这是一个使用 Vim 命令行功能的小型非交互式示例来说明这一点(换句话说,您可以将以下内容复制并粘贴到终端中以运行它)。 xxd
显示生成文件的十六进制转储。
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。
【讨论】:
/r 被视为按下 Enter/Return 键。它适用于所有平台。 另见Why is \r a newline for Vim?。 我希望这适用于经典 vi。在 AIX v6.1 上,\r
不能这样工作。但是您可以按Ctrl-V
Enter
代替输入\r
,这样就可以了。
我迟到了。如果\r
插入<CR>
和\n
插入null,我将如何用回车替换某些内容?
@SunnyRaj 你确定 CR 和 LF 的历史吗?我的印象是,最初 LF 将纸张向前移动一排但不移动打印头,而 CR 移动打印头但不移动纸张。因此,如果您的操作系统在打印之前没有转换输入,您就不能只使用 LF 或 CR 来获得正确的输出。 MS DOS 使用原始打印机数据作为文本文件格式,Mac OS 使用 CR 并将其转换为打印机的原始格式,UNIX 使用 LF 并将其转换为打印机的原始格式。【参考方案2】:
在语法中s/foo/bar
、\r
和\n
有不同的含义,具体取决于上下文。
短:
对于foo
:
\r
== "回车" (CR
/ ^M
)\n
== 在 Linux/Mac 上匹配 "换行" (LF
),在 Windows 上匹配 CRLF
对于bar
:
\r
== 在 Linux/Mac 上产生 LF
,在 Windows 上产生 CRLF
\n
== "null byte" (NUL
/ ^@
)
在 linux 中编辑文件时(即在网络服务器上)最初在 windows 环境中创建并上传(即 FTP/SFTP) - 您在 vim 中看到的所有 ^M
都是 CR
哪个 linux 没有翻译,因为它只使用 LF
's 来描述换行符。
更长(带有 ASCII 数字):
NUL
== 0x00 == 0 == Ctrl + @ == ^@
显示在 vimLF
== 0x0A == 10 == Ctrl + JCR
== 0x0D == 13 == Ctrl + M == ^M
在 vim 中显示
这是ASCII control characters 的列表。通过 Ctrl + V,Ctrl + ---key--- 将它们插入 Vim。
在 Bash 或其他 Unix/Linux shell 中,只需键入 Ctrl + ---key---。
在 Bash 中尝试 Ctrl + M。这与按 Enter 相同,因为 shell 会意识到这意味着什么,即使 Linux 系统使用换行符来分隔行。
要在 bash 中插入文字,在它们前面加上 Ctrl + V 也可以。
在 Bash 中尝试:
echo ^[[33;1mcolored.^[[0mnot colored.
这使用ANSI escape sequences。通过 Ctrl + V, Esc 插入两个^[
。
你也可以试试 Ctrl + V,Ctrl + M, Enter,它会给你这个:
bash: $'\r': command not found
还记得上面的\r
吗? :>
这个ASCII control characters 列表与完整的ASCII symbol table 不同,通过Ctrl 键(哈哈)插入控制台/伪终端/Vim 的控制字符可以是在那里找到。
而在 C 和大多数其他语言中,您通常使用八进制代码来表示这些“字符”。
如果你真的想知道这一切的来源:The TTY demystified。这是您会遇到的有关此主题的最佳链接,但请注意:有龙。
TL;DR
通常foo
= \n
和bar
= \r
。
【讨论】:
所以我很好奇你如何用回车替换一个字符 @codeshot:s/x/^M/g
应该可以。通过ctrl-v
插入^M
,后跟ctrl-m
。
谢谢 sjas,你知道这个问题是有史以来最奇怪的问题之一。 1008 票投给了答案,它基本上只是说“vim 做了你发现的事情。那是因为 vim 做了你发现的事情。永远不要忘记 vim 做你发现的事情。”我希望找到模式中有趣字符的代码候选清单,替换和奇怪的原因,这样它很容易记住和预测其他类似的奇怪。那会得到我的投票。
@codeshot ascii 控制字符列表可能会对您有所帮助。请参阅cs.tut.fi/~jkorpela/chars/c0.html 以获取更多参考。我将更新我的答案以包含两个链接。【参考方案3】:
这是我认为的最佳答案,但在表格中会更好:
Why is \r a newline for Vim?
所以,重新措辞:
您需要使用\r
在正则表达式替换中使用换行符(ASCII 0x0A
,Unix 换行符),但这是替换所特有的 - 您通常应该继续使用 \n
换行和\r
用于回车。
这是因为 Vim 使用 \n
来代替 NIL 字符(ASCII 0x00
)。您可能希望 NIL 改为 \0
,释放 \n
以使其通常用于换行,但 \0
在正则表达式替换中已经有意义,因此它被转移到 \n
。因此,进一步将换行符从\n
移动到\r
(在正则表达式模式中是回车符,ASCII 0x0D
)。
NB:^M
(Linux 上的Ctrl + V Ctrl + M)插入换行符用于正则表达式替换而不是其他人建议的回车(我刚刚尝试过)。
另请注意,Vim 会在根据文件格式设置保存到文件时转换换行符,这可能会造成混淆。
【讨论】:
【参考方案4】:如果您需要对整个文件执行此操作,我还建议您可以从命令行尝试:
sed 's/\\n/\n/g' file > newfile
【讨论】:
请注意,这需要 GNU sed。试试printf 'foo\\nbar\n' | sed 's/\\n/\n/g'
看看它是否可以在您的系统上运行。 (感谢 freenode 上 #bash 的好人提出的这个建议。)
是的,但问题是关于 Vim。有堆栈溢出问题How can I replace a newline (\n) using sed?.【参考方案5】:
但如果必须替换,则以下方法可行:
:%s/\n/\r\|\-\r/g
在上面,每下一行都被下一行替换,然后是|-
,又是一个新行。这在 wiki 表格中使用。
如果文字如下:
line1
line2
line3
改为
line1
|-
line2
|-
line3
【讨论】:
【参考方案6】:这是对我有用的答案。来自这个人:
----引用Use the vi editor to insert a newline char in replace
我必须做的其他事情,但我不记得了,然后必须查找。
在 vi 中,要在搜索和替换中插入换行符,请执行以下操作:
:%s/look_for/replace_with^M/g
上述命令会将所有“look_for”实例替换为“replace_with\n”(\n 表示换行符)。
要获得“^M”,请输入组合键 Ctrl + V,然后(释放所有键)按 Enter kbd> 键。
【讨论】:
【参考方案7】:从Eclipse 开始,^M
字符可以嵌入到一行中,您希望将它们转换为换行符。
:s/\r/\r/g
【讨论】:
【参考方案8】:这是诀窍:
首先,将您的 Vi(m) 会话设置为允许使用特殊字符(即:换行符)进行模式匹配。可能值得将此行放入您的 .vimrc 或 .exrc 文件中:
:set magic
接下来,做:
:s/,/,^M/g
要获取^M
字符,请键入Ctrl + V 并按Enter。在 Windows 下,执行 Ctrl + Q,Enter。我能记住这些的唯一方法就是记住它们的意义是多么渺小:
答:用来表示换行符最差的控制字符是什么?
B:
q
(因为它通常表示“退出”)或v
,因为键入 Ctrl + C 非常容易误杀编辑。答:就这样吧。
【讨论】:
我在 Windows 上使用 GVim,我既不需要:set magic
(它也不在我的 ~/_vimrc 中)或 ctrl-q
。只需一个简单的ctrl-v
然后回车就可以为我创建^M
字符。
C-v 不代表换行符;这是“转义下一个文字字符”命令。我不知道 C-v 是什么的助记符,但它在心理上没有映射到换行符是有原因的。
Ctrl-v 是“逐字”的助记符 - 即将按下的下一个键转义到其“逐字”键码/字符。在 Windows 中,它是粘贴:让事情变得熟悉。 Ctrl-Q 可能是“(un)Quote”。无论如何,这很愚蠢-但您可以在二进制文件中使用它-例如通过 Ctrl-Z 搜索 Ctrl-A(我猜是 Ascii 1-26)。
Ctrl-C
实际上并没有杀死编辑器,尽管它可以取消你回到正常模式。 Ctrl-V
表示逐字逐句,Ctrl-Q
表示有人错误地加载了$VIMRUNTIME/mswin.vim
配置文件。你不需要mswin。只需使用您自己的 vimrc 即可。
哇——这太棒了。我以前做sed -n l
直到现在。很高兴知道在 vim 中使用 Ctrl-v
也可以实现同样的效果。【参考方案9】:
在 Windows 上使用 Vim,使用 Ctrl + Q 代替 Ctrl + V。
【讨论】:
【参考方案10】:你需要使用:
:%s/,/^M/g
要获取^M
字符,请按Ctrl + v,然后按Enter。
【讨论】:
我必须执行\r
可以为您完成这里的工作。
【讨论】:
以上是关于如何在 Vim 中用换行符替换字符的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 C# 在给定文本中用忽略空格、回车或换行符替换字符串