grep --color=auto 当 ^M 位于颜色匹配内时中断

grep --color=auto 当 ^M 位于颜色匹配内时中断

我有 2 个类似的文件(dos.txt 和 unix.txt),其文本The quick brown fox jumps\n over the lazy dog.的行结尾不同。当我在行尾搜索单词时,dos.txt 的输出为空:

$ grep -E 'jumps^M?$' dos.txt unix.txt

unix.txt:The quick brown fox jumps

Grep 找到一些东西但不打印它。 grep 的实际输出如下所示:

$ grep -E --color=always 'jumps^M?$' dos.txt unix.txt | cat -v
^[[35m^[[Kdos.txt^[[m^[[K^[[36m^[[K:^[[m^[[KThe ... ^[[01;31m^[[Kjumps^M^[[m^[[K
^[[35m^[[Kunix.txt^[[m^[[K^[[36m^[[K:^[[m^[[KThe ... ^[[01;31m^[[Kjumps^[[m^[[K

所以看起来唯一的区别是 ^M 位于彩色输出内部,它导致整行消失。我该如何解决这个问题(无需使用 dos2unix 或类似工具转换 dos 文件)?

答案1

经过一番寻找^[[K转义序列后,阅读了半本关于VT100终端并检查man grep我发现将环境变量设置GREP_COLORS

GREP_COLORS=ne

给出所需的输出:

$ export GREP_COLORS=ne
$ grep -E --color=always 'jumps^M?$' dos.txt unix.txt
dos.txt:The quick brown fox jumps
unix.txt:The quick brown fox jumps

$ grep -E --color=always 'jumps^M?$' dos.txt unix.txt | cat -v
^[[35mdos.txt^[[m^[[36m:^[[mThe ... ^[[01;31mjumps^M^[[m
^[[35munix.txt^[[m^[[36m:^[[mThe ... ^[[01;31mjumps^[[m

grep手册页:

ne     Boolean  value  that prevents clearing to the
       end of line using Erase in Line (EL) to Right
       (\33[K)  each  time  a  colorized  item ends.
       This is needed on terminals on  which  EL  is
       not  supported.   It  is  otherwise useful on
       terminals  for  which  the   back_color_erase
       (bce)  boolean  terminfo  capability does not
       apply, when the chosen  highlight  colors  do
       not  affect the background, or when EL is too
       slow or causes too much flicker.  The default
       is false (i.e., the capability is omitted).

就我而言,即使我将突出显示颜色设置为更改背景的颜色,效果也很好:

export GREP_COLORS="ne:mt=41;38"

现在有趣的问题是为什么^[[K会产生这个空行。

字符^M表示回车而不进入下一行:

$ echo -e "start^Mend"
endrt

^[[K清除光标右侧的行,然后写入该行的其余部分:

$ echo -e "start\033[Kend"
startend

但是,当您放在^M前面时^[[K,它会删除内容:

$ echo -e "start^M\033[Kend"
end

写完后开始光标转到行首,然后^[[K删除所有内容并写入该行的其余部分。如果grep输出第一行将所有内容写入单词跳跃,然后返回到行首^M,写入无害的^[[m序列,^J然后转到新行。这就是为什么在清除整行^[[K之后。^M

答案2

您可以通过 tr(1) 管道输出并删除回车符。 tr -d '\r'将删除所有回车符。

这有效:

grep --color=always -E 'jumps' dos.txt unix.txt | tr -d '\r'

(也适用于^M?。)

提示:当您怀疑输出可能包含不安全字符时,将输出通过管道传输到 less(1)。

相关内容