我有 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)。