我有 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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
所以看起来唯一的区别是 ^M 在彩色输出里面,它会导致整行消失。我该如何解决这个问题(不使用 dos2unix 或类似工具转换 dos 文件)?
mx0*_*mx0 11
在搜索^[[K
转义序列后,阅读了一半关于VT100 终端的书并检查man grep
我发现将环境变量设置GREP_COLORS
为
GREP_COLORS=ne
Run Code Online (Sandbox Code Playgroud)
提供所需的输出:
$ 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
Run Code Online (Sandbox Code Playgroud)
从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).
Run Code Online (Sandbox Code Playgroud)
在我的情况下,即使我将高亮颜色设置为改变背景的东西,它也能很好地工作:
export GREP_COLORS="ne:mt=41;38"
Run Code Online (Sandbox Code Playgroud)
现在有趣的问题是为什么^[[K
会产生这个空行。
字符^M
表示不进入下一行的回车:
$ echo -e "start^Mend"
endrt
Run Code Online (Sandbox Code Playgroud)
^[[K
清除从光标到右侧的行,然后写入行的其余部分:
$ echo -e "start\033[Kend"
startend
Run Code Online (Sandbox Code Playgroud)
但是,当您^M
在^[[K
删除内容之前放置时:
$ echo -e "start^M\033[Kend"
end
Run Code Online (Sandbox Code Playgroud)
写完开始光标到行首然后^[[K
删除所有内容并写入行的其余部分。在grep
输出的情况下,第一行将所有内容写入单词跳转,然后返回到行首^M
,写入无害^[[m
序列^J
,然后转到新行。这就是为什么^[[K
在^M
清除整行之后。