我正在尝试用新行替换当前文件中的每个 ,
:
:%s/,/\n/g
但它会插入看起来像 ^@
的东西,而不是实际的换行符。该文件未处于 DOS 模式或任何状态。
我应该怎么办?
如果您像我一样好奇,也请检查问题Why is \r a newline for Vim?。
使用 \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。
这是诀窍:
首先,将您的 Vi(m) 会话设置为允许使用特殊字符进行模式匹配(即:换行符)。将这一行放在你的 .vimrc 或 .exrc 文件中可能是值得的:
:set magic
接下来,执行:
:s/,/,^M/g
要获取 ^M
字符,请键入 Ctrl + V 并按 Enter。在 Windows 下,执行 Ctrl + Q,Enter。我能记住这些的唯一方法是记住它们的意义有多大:
A: 用来表示换行符的最差控制字符是什么? B:要么是 q(因为它通常表示“退出”)要么是 v,因为很容易误按 Ctrl + C 并杀死编辑器。答:就这样吧。
:set magic
(它也不在我的 ~/_vimrc 中)也不需要 ctrl-q
。只需一个简单的 ctrl-v
然后回车就可以为我创建 ^M
字符。
Ctrl-C
实际上并没有杀死编辑器,尽管它可以取消您回到正常模式。 Ctrl-V
表示逐字,Ctrl-Q
表示有人错误地加载了 $VIMRUNTIME/mswin.vim
配置文件。你不需要mswin。只需使用您自己的 vimrc 即可。
sed -n l
到现在。很高兴知道在 vim 中使用 Ctrl-v
也可以达到同样的效果。
在语法 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
都是 linux 所做的 CR
不翻译,因为它仅使用 LF
来描述换行符。
更长(带有 ASCII 数字):
NUL
== 0x00 == 0 == Ctrl + @ == ^@
显示在 vim
LF
== 0x0A == 10 == Ctrl + J
CR
== 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;博士
通常 foo
= \n
,bar
= \r
。
:s/x/^M/g
应该可以。通过 ctrl-v
和 ctrl-m
插入 ^M
。
你需要使用:
:%s/,/^M/g
要获取 ^M
字符,请按 Ctrl + v,然后按 Enter。
\r
可以为您完成这里的工作。
在 Windows 上使用 Vim,使用 Ctrl + Q 代替 Ctrl + V。
这是我认为的最佳答案,但在表格中会更好:
所以,改写:
您需要使用 \r
在正则表达式替换中使用换行符(ASCII 0x0A
,Unix 换行符),但这是替换所特有的 - 您通常应该继续使用 \n
作为换行符和\r
用于回车。
这是因为 Vim 在替换中使用 \n
来表示 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
(Ctrl + V Ctrl + M 在 Linux 上)在用于正则表达式替换而不是其他人建议的回车(我刚刚尝试过)。
另请注意,Vim 将根据其文件格式设置保存到文件时转换换行符,这可能会造成混淆。
但是,如果必须替换,则以下内容有效:
:%s/\n/\r\|\-\r/g
在上面,每一下一行都被下一行替换,然后是 |-
并再次换行。这用于 wiki 表格。
如果文字如下:
line1
line2
line3
它改为
line1
|-
line2
|-
line3
这是对我有用的答案。来自这个人:
----引用 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 键。
如果您需要对整个文件执行此操作,我还建议您可以从命令行尝试:
sed 's/\\n/\n/g' file > newfile
printf 'foo\\nbar\n' | sed 's/\\n/\n/g'
看看它是否可以在您的系统上运行。 (感谢 freenode 上#bash 的好人提出这个建议。)
不定期副业成功案例分享
\r
不能这样工作。但是您可以按Ctrl-V
Enter
代替输入\r
,它可以工作。\r
插入<CR>
而\n
插入 null,我将如何用回车替换某些内容?