保持 grep 的输出重定向到 less 时的颜色高亮
问题
使用 grep
搜索,比如:
$ cat a.txt | grep -a "word"
在输出结果里,匹配到的字符会通过颜色高亮显示,方便定位;
但如果输出结果比较多,有时还带上下文一起,就需要分屏显示,比如这样使用:
$ cat a.txt | grep -a "word" | less -NR
这时,匹配到的字符没有了颜色高亮,即使 less
已经加上了 -R
选项也不行。
走读实现代码
浏览了 grep
源代码里的相关逻辑,主要是 color_option
变量的赋值和使用:
定义:
/* If nonzero, use color markers. */
static int color_option;
根据命令行参数初始化:
case COLOR_OPTION:
if (optarg)
{
if (!strcasecmp (optarg, "always") || !strcasecmp (optarg, "yes")
|| !strcasecmp (optarg, "force"))
color_option = 1;
else if (!strcasecmp (optarg, "never") || !strcasecmp (optarg, "no")
|| !strcasecmp (optarg, "none"))
color_option = 0;
else if (!strcasecmp (optarg, "auto") || !strcasecmp (optarg, "tty")
|| !strcasecmp (optarg, "if-tty"))
color_option = 2;
else
show_help = 1;
}
else
color_option = 2;
break;
如果命令行参数里没有指定,那么进行自动判断:
if (color_option == 2)
color_option = possibly_tty && should_colorize () && isatty (STDOUT_FILENO);
init_colorize ();
解决
color_option
默认的是 auto
自动判断,即在输出时,检查环境变量 TERM
以及接口 int isatty(int fd)
,如果结果是输出到控制台,那么就加上颜色高亮。而对于通过管道输出到 less
,就没有颜色高亮了。
所以,对于这个问题,可以加上 --color=always
选项,强制要求颜色高亮,比如:
$ cat a.txt | grep -a --color=always "word" | less -NR
这样就可以了。