首页 > 解决方案 > 如果找到的行包含 ^M(必须是 unix 新行)字符,为什么 grep 不能显示它们?

问题描述

我的 vimrc 文件中有宏行,例如:

let @i = "oif (^[a) {^[a^M}^[k0f)"

其中 "^[" 和 "^M" 是在插入模式下通过 "Ctrl-V" 输入的字符,所以它们必须是 Escape 和 Newline (我使用的是 Linux,而 Vim 配置为使用 '\n ' 换行符,但我不知道 vimrc 文件中这个字符到底是什么)

当我搜索这样一行时,grep -B 2 'i = "' ~/.vimrc我看到一个完全损坏的输出:

hi Comment cterm=none ctermbg=226 ctermfg=009 guibg=#ffff00 guifg=#ff0000

}0f)"i = "oif () {

虽然我想要:

hi Comment cterm=none ctermbg=226 ctermfg=009 guibg=#ffff00 guifg=#ff0000

let @i = "oif (^[a) {^[a^M}^[k0f)"

或者至少类似的东西,第三行以let @i. 但是我看到}0f)"i = "oif () {了,没有任何迹象let @i

我试图调查一下,发现它可以正常工作,直到该行具有“^M”字符。

谁能说一下如何解决它,或者至少解释一下那里发生了什么?

标签: vimterminalgrepnewlineansi-escape

解决方案


grep正在向终端发送转义序列 (例如^[aand ^[k;请参阅下面的 Amadan 的评论)和控制字符 ( ^M),它们会弄乱输出,当被其他命令过滤时会显示:

grep -B 2 'i = "' ~/.vimrc | cat -v

或者

grep -B 2 'i = "' ~/.vimrc | less

这就是cat 的手册页所说的-v

-v, --show-nonprinting
    use ^ and M- notation, except for LFD and TAB

这也是从少的手册页中截取的相关内容:

Control and binary characters are displayed in standout (reverse video).  Each
such character is displayed in caret notation if possible (e.g. ^A for control-
A).  Caret notation is used only if inverting the 0100 bit results in a normal
printable character.  Otherwise, the character is displayed as a hex number in
angle brackets.

这些控制序列通常用于向终端发送不可打印的字符,允许用户通过添加(前景和背景)颜色、移动光标等来自定义终端输出。

无效的转义序列如^[a^[k被忽略,因此如果宏定义如下,您将遇到相同的问题:

let @i = "oif () {^M}0f)"

^M称为回车,它告诉终端在打印其余输出之前将光标移动到行首(这将覆盖先前的输出)。这类似于0 在正常模式下键入,然后按R然后输入

}0f)"

自己在:

let @i = "oif () {^M}0f)"

我希望这个答案是有帮助的。


推荐阅读