我有一些文本行,我正在尝试进入寄存器,然后将寄存器的内容回显到生成 vim 进程的终端,以便在 vim 退出后文本将在终端窗口中可见。
我可以在一行文本上正常工作,但是一旦添加了换行符/换行符,所有执行此操作的尝试都会失败。
使用包含以下内容的示例文件:
1 A
2 ab
3 abc
4 abce
5 abcef
6 abcefg
首先,我通过":%y m"将文件内容放入寄存器("m")中 然后我尝试":exe '!echo '@m">
这会将第一行文本回显到终端
一个
但是 vim 将字母"a"后面的第一个换行符/换行符视为按 Enter 键,因此它会抛出以下错误消息
E492:不是编辑器命令:abce^@abcef^@abcefg^@^@
我在":d ebug"模式下运行以下命令,希望用换行符替换^@字符()
:echo substitute(strtrans(@m),"^@",'',"g")
:echo substitute(strtrans(@m),'^@','',"g")
我尝试过双引号和单引号,并且尝试从字面上键入插入符号和与号,以及使用特殊字符 CTRL-V+CTRL-J 不幸的是,在调试模式下,我可以看到输出始终如下:
a^@ab^@abc^@abce^@abcef^@abcefg^@^@
printf 也会发生同样的情况。 我已经对换行符、空字符的歧义以及 vim 如何在寄存器中处理这些进行了一些复习,但不清楚我想要实现的目标是否合理。
:h nl-used-for-nul
解释说,换行符'n'
由 Vim 显示为^@
。所以,是的,正如你已经说过的,你将实际的换行符发送到 shell。
接下来,将一个字符'n'
(ASCII 0x0a)替换为两个字符"n"
(0x5c 0x6e)的一般想法也是正确的。您希望外壳程序接收foonbar
。
:echo substitute(@m, 'n', 'n', 'g')
a
ab
abc
abce
abcef
abcefg
输出显然仍然包含实际的换行符,因此我们必须转义这些字符。
:echo substitute(@m, 'n', '\n', 'g')
anabnabcnabcenabcefnabcefgn
这看起来不错!因此,让我们尝试一下您想到的整个命令:
:execute '!echo' substitute(@m, 'n', '\n', 'g')
anabnabcnabcenabcefnabcefgn
Press ENTER or type command to continue
嗯?好吧,:execute
计算字符串,因此消耗"一级字符串"。因此,我们必须再次转义换行符,而我们必须将每个"字符串级别"的转义数量加倍。
所以,我们不仅需要anabnabc
,还需要a\nab\nabc
:
:echo substitute(@m, 'n', '\\n', 'g')
a\nab\nabc\nabce\nabcef\nabcefg\n
:execute '!echo' substitute(@m, 'n', '\\n', 'g')
a
ab
abc
abce
abcef
abcefg
Press ENTER or type command to continue
🎉
附加说明:
- 当使用双引号处理转义字符时,与单引号字符串相反,我们将不得不再次将转义的数量加倍:
substitute(@m, 'n', "\\\\n", 'g')
. - 如果要去除尾随换行符,请使用
trim(@)
。
我想你正在寻找shellescape()
:
:execute "!echo " . shellescape(@@, 1)
使用非零参数作为第二个参数,<NL>
字符也会被转义。
有关更多帮助,请参阅:
:h shellescape()