我正在尝试将当前文件中的每个,
替换为一个新行:
:%s/,/\n/g
但它插入的看起来像是^@
而不是实际的换行符。该文件并非处于DOS模式或其他模式。
我该怎么办?
如果你像我一样好奇,也可以查看这个问题:为什么\r在Vim中是一个新行符?
我正在尝试将当前文件中的每个,
替换为一个新行:
:%s/,/\n/g
但它插入的看起来像是^@
而不是实际的换行符。该文件并非处于DOS模式或其他模式。
我该怎么办?
如果你像我一样好奇,也可以查看这个问题:为什么\r在Vim中是一个新行符?
\r
代替\n
。用\n
代替会在文本中插入一个空字符。要获得换行符,请使用\r
。但是,在搜索换行符时,仍需使用\n
。这种不对称是由于\n
和\r
执行的操作略有不同:
\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
不能像这样使用。但是你可以在输入\r
的位置按Ctrl-V
和Enter
键,这样就可以实现相同的效果。 - eksortso\r
插入<CR>
,\n
插入空字符,如何用回车替换某些内容? - Mr. Llama这里是技巧:
首先,设置您的Vi(m)会话以允许使用特殊字符(例如:换行符)进行模式匹配。最好将此行放在您的 .vimrc 或 .exrc 文件中:
:set magic
接下来,执行:
:s/,/,^M/g
要得到字符^M
,请键入Ctrl + V并按Enter。在Windows下,请执行Ctrl + Q,Enter。我唯一能记住这些操作的方法就是记住它们似乎没有什么意义:
A:用哪个控制字符来表示换行会最糟糕?
B:要么是
q
(因为它通常表示“退出”),要么是v
,因为打错键很容易导致意外终止编辑器。A:就这样吧。
:set magic
(在我的~/_vimrc中也没有)或者Ctrl-Q
。只需要简单的按下ctrl-v
,然后回车键就可以为我创建^M
字符。 - Chris PhillipsCtrl-C
并不能真正地杀死编辑器,尽管它可以将您取消回到正常模式。 Ctrl-V
表示逐字,而Ctrl-Q
表示有人错误地加载了$VIMRUNTIME/mswin.vim
配置文件。 您不需要mswin。 只需使用自己的vimrc即可。 - 00danised -n l
,现在知道在 vim 中可以用 Ctrl-v
实现相同的功能。 - arpit \r
和 \n
根据上下文具有不同的含义。
对于foo
:
\r
==“回车符”(CR
/ ^M
)
\n
== 在Linux / Mac上匹配“换行符”(LF
),在Windows上匹配CRLF
对于bar
:
\r
== 在Linux / Mac上产生LF
,在Windows上产生CRLF
\n
==“空字节”(NUL
/ ^@
)
在Linux(即Web服务器)中编辑最初在Windows环境中创建并上传(即FTP / SFTP)的文件时 - vim中看到的所有^M
都是CR
,Linux不进行转换,因为它仅使用LF
表示换行。
NUL
== 0x00 == 0 == Ctrl + @ == vim中显示的^@
LF
== 0x0A == 10 == Ctrl + J
CR
== 0x0D == 13 == Ctrl + M == vim中显示的^M
这是 ASCII控制字符列表。通过 Ctrl + V , Ctrl + --- key --- 在Vim中插入它们。
在Bash或其他Unix / Linux shell中,只需键入 Ctrl + --- key --- 。
在Bash中尝试 Ctrl + M 。与Linux系统使用换行符进行行定界不同,它与按 Enter 相同,因为shell意识到其意义。
要在Bash中插入文字,可以在其前面添加 Ctrl + V 。
在Bash中尝试:
echo ^[[33;1mcolored.^[[0mnot colored.
这里使用了ANSI转义序列。通过Ctrl + V, Esc键插入两个^[
。
您也可以尝试使用Ctrl + V,Ctrl + M,Enter,它会给您呈现这样的结果:
bash: $'\r': command not found
记得前面提到的 \r
吗? :>
这个ASCII控制字符列表不同于一个完整的ASCII符号表,因为控制字符是通过Ctrl键(哈哈)插入到控制台/伪终端/Vim中的,所以它们可以在那里找到。
而在C和大多数其他语言中,通常使用八进制代码来表示这些'字符'。
如果你真的想知道所有这些的来历: TTY解密。这是你会遇到的关于这个话题最好的链接,但要小心:龙在其中。
太长;没看
通常foo
=\n
,bar
=\r
。
:s/x/^M/g
应该可以解决问题。通过 ctrl-v
然后跟着 ctrl-m
插入 ^M
。 - sjas您需要使用:
:%s/,/^M/g
想要得到^M
这个字符,需按下Ctrl + v再按下Enter键。
\r
可以在这里为您完成工作。
这是我认为最好的答案,但如果用表格会更好:
重新表述一下:
在正则表达式替换中需要使用\r
来表示换行(ASCII 0x0A
,即Unix换行符),但这只适用于替换操作 - 你通常应该继续使用\n
来表示换行和\r
表示回车。
这是因为Vim在替换操作中使用\n
表示NIL字符(ASCII 0x00
)。你可能认为NIL应该是\0
,以便将\n
用于其通常的作用——表示换行符,但\0
在正则表达式替换中已经有了意义,所以它被移位到了\n
。因此,进一步将换行符从\n
移位到\r
(在正则表达式模式中,\r
是回车符,ASCII代码为0x0D
)。
字符 | ASCII码 | C表示方式 | 正则表达式匹配 | 正则表达式替换 -------------------------+----------+-----------+---------------+------------------------ NIL | 0x00 | \0 | \0 | \n 换行符(Unix换行符) | 0x0a | \n | \n | \r 回车符 | 0x0d | \r | \r | <未知>
注意: ^M
(在Linux中使用Ctrl + VCtrl + M)在正则表达式替换中插入的是一个换行符而不是回车符,这与其他人的建议不同(我刚试过)。
需要注意的是,当Vim根据其文件格式设置保存文件时,会翻译换行符号,这可能会使事情变得混乱。
:%s/\n/\r\|\-\r/g
|-
和一个新行。这在维基表格中经常被使用。line1
line2
line3
它已发生改变
line1
|-
line2
|-
line3
如果你需要对整个文件进行操作,有人建议你可以尝试从命令行开始:
sed 's/\\n/\n/g' file > newfile
printf 'foo\\nbar\n' | sed 's/\\n/\n/g'
查看它是否适用于您的系统。(感谢freenode上#bash的好心人提供此建议。) - Evan Donovan