彩色grep-使用突出显示的匹配项查看整个文件


509

我发现grep--color=always标志非常有用。但是,grep仅打印具有匹配项的行(除非您请求上下文行)。鉴于它打印的每一行都有一个匹配项,因此突出显示并没有添加尽可能多的功能。

我真的很想要cat一个文件,然后看到整个文件都带有突出显示的模式匹配项。

有什么办法可以让grep打印正在读取的每一行,而不管是否有匹配项?我知道我可以编写一个脚本在文件的每一行上运行grep,但是我很好奇standard是否可以实现grep


1
如果您想为一种以上的图案提供多种颜色(即错误,警告,信息等消息),请使用sed。该sed解决方案以增加复杂性为代价为您提供了多种颜色(而不是大约30个字符,而您拥有大约60个字符)。
特雷弗·博伊德·史密斯

使用sed,您甚至可以突出显示+返回退出代码,请参见示例: askubuntu.com/a/1200851/670392
Noam Manos

Answers:


797

以下是一些方法:

grep --color -E 'pattern|$' file
grep --color 'pattern\|$' file
egrep --color 'pattern|$' file

152
| $技巧很整洁!做得好,我必须记住这一点。对于那些不懂正则表达式的人,“ pattern | $”将匹配具有您要搜索的模式的行,并搜索具有结尾的AND行,即所有行。由于行尾实际上不是任何字符,因此输出的彩色部分将只是您的图案。谢谢瑞安!
zslayton

55
您也可以省略“$”: egrep --color "pattern|" file(信用stackoverflow.com/a/7398092/50979
13ren

15
@Zack,“ |” 运算符是OR运算符,而不是AND,
JBoy

16
@JBoy,我以常规英语方式而不是布尔逻辑方式使用“ AND”。您是正确的,它确实是一个“或”运算符-它与此匹配。:P好的澄清。
zslayton 2013年

12
如果匹配多个模式,则似乎需要“ $”。egrep --color "pattern1|pattern2|$"。否则颜色突出显示不会发生。
ZaSter 2013年

91

这是一样的东西。很有可能,您无论如何都会减少使用,因此请尝试以下操作:

less -p pattern file

它将突出显示模式,并跳至文件中第一个出现的模式。


4
也可用于使用以下命令的管道(从stding中读取)-… | less -p pattern -
phk

3
@phk:您甚至可以省略破折号。
暂停,直到另行通知。

另外,添加-i选项将使匹配大小写不敏感,如中所述less -ip pattern file
Steveb

...,并且如果管道采用ANSI色输入,请提供less以下-R开关:… | less -Rip introduction -
Abdull

48

我想推荐ack-比对程序员有用的强大搜索工具grep更好

$ ack --color --passthru --pager =“ $ {PAGER:-less -R}”模式文件
$ ack --color --passthru模式文件| 少-R
$ export ACK_PAGER_COLOR =“ $ {PAGER:-less -R}”
$ ack --passthru模式文件

我喜欢它,因为它默认为目录的递归搜索(并且比聪明得多grep -r),支持完整的Perl正则表达式(而不是POSIXish regex(3)),并且在搜索许多文件时具有更好的上下文显示。


2
但是,当我确定它必须在那里时,它有时会找不到我想要的东西。ack是聪明,但有时太聪明,它已排除的文件类型,该命中英寸
迈克尔Piefel

4
@MPi ack -a将搜索所有的文件类型,同时还排除.git/ .svn/
ephemient

1
但是,很酷的是ack不会搜索我的图像,所以搜索-a太多。我添加--type-set=freemarker=.ftl~/.ackrc,举了一个例子。
Michael Piefel

3
通过一些配置调整,grep已经可以完成ack所做的一切,而且速度更快,并且从未像ack的白名单有时那样忽略结果。也许将首选的grep设置保存在.bashrc中。我的读物:函数grp(){GREP_OPTIONS =“-rI --color --exclude-dir = \。git --exclude = tags” grep“ $ @”
乔纳森·哈特利2013年

22

您可以highlighthttps://github.com/kepkin/dev-shell-essentials使用我的脚本

这是更好的grep,因为你可以突出显示每场比赛有其自己的颜色

$ command_here | highlight green "input" | highlight red "output"

Github项目的屏幕截图


3
该问题明确要求使用解决方案grep,这是运行* nix的计算机上的标准实用程序。
zslayton

1
这个脚本很好,但是不如colout另一个答案中提到的那么好。
乔纳森·哈特利

@JonathanHartley为什么会这样?我认为没有理由。此外,该脚本使用的实现比起来简单得多colout,如果您想检查它的作用,那么这很好。
HelloGoodbye

@HelloGoodbye是的,很公平。我应该推迟判决。colout更加彻底和强大,但是您使用和反向工程相应地更加复杂是正确的。
乔纳森·哈特利

@JonathanHartley它更强大!
HelloGoodbye

19

您也可以创建一个别名。在您的.bashrc(或osx上的.bash_profile)中添加此功能

function grepe {
    grep --color -E "$1|$" $2
}

您现在可以使用如下别名:“ ifconfig | grepe inet”或“ grepe css index.html”。

(PS:别忘source ~/.bashrc了在当前会话上重新加载bashrc)


如果您的系统上有egrep,也可以只使用egrep。
2015年

1
用这种方法减少损失的颜色信息。您将如何预防?
康纳·克拉克

5
@Hoten使用--color=always代替--color
limp_chimp

3
并且,使用来less解释颜色代码less -R
伊莱亚·卡根

$ 2的未报价使用不是空白的。在bash中,我宁愿执行函数grepe(){local pattern =“ $ 1” shift egrep --color“ $ pattern | ^”“ $ @”}抱歉,格式混乱。
罗伯特·克莱姆

16

使用colout程序:http : //nojhan.github.io/colout/

它旨在向文本流中添加颜色突出显示。给定正则表达式和颜色(例如“红色”),它会复制文本流并突出显示匹配项。例如:

# cat logfile but highlight instances of 'ERROR' in red
colout ERROR red <logfile

您可以链接多个调用以添加多个不同的颜色突出显示:

tail -f /var/log/nginx/access.log | \
    colout ' 5\d\d ' red | \
    colout ' 4\d\d ' yellow | \
    colout ' 3\d\d ' cyan | \
    colout ' 2\d\d ' green

或者,您可以通过使用具有N个组的正则表达式(正则表达式的括号部分),然后用逗号分隔N种颜色的列表来实现相同的目的。

vagrant status | \
    colout \
        '\''(^.+  running)|(^.+suspended)|(^.+not running)'\'' \
        green,yellow,red

1
如其他地方所述,该问题明确要求使用grep解决方案,grep是运行* nix的计算机上的标准实用程序。
zslayton 2015年

4
@Zack好的,对不起。实际上,如果您将问题扩展到之外grep,并且已经在答案中进行了扩展,则它是colout解决您遇到的问题的最佳解决方案,也是我所知道的最佳解决方案。根据UNIX的哲学,程序应该写得很好。因为grep它正在过滤文本流。因为colout它是着色或突出显示文本流。
user2683246

这是最好的答案,因为它可以应用多个不同颜色的高光,并且colout是一种用途广泛的工具。一次学习,用它在许多情况下,而不是一个学习工具,亮点日志文件,另一个亮点测试输出等
乔纳森·哈特利

9

我使用O'Reilly的“ Linux Server Hacks”中的rcg。它非常适合您想要的内容,并且可以突出显示具有不同颜色的多个表达式。

#!/usr/bin/perl -w
#
#       regexp coloured glasses - from Linux Server Hacks from O'Reilly
#
#       eg .rcg "fatal" "BOLD . YELLOW . ON_WHITE"  /var/adm/messages
#
use strict;
use Term::ANSIColor qw(:constants);

my %target = ( );

while (my $arg = shift) {
        my $clr = shift;

        if (($arg =~ /^-/) | !$clr) {
                print "Usage: rcg [regex] [color] [regex] [color] ...\n";
                exit(2);
        }

        #
        # Ugly, lazy, pathetic hack here. [Unquote]
        #
        $target{$arg} = eval($clr);

}

my $rst = RESET;

while(<>) {
        foreach my $x (keys(%target)) {
                s/($x)/$target{$x}$1$rst/g;
        }
        print
}


6

我将此添加到我的.bash_aliases中:

highlight() {
  grep --color -E "$1|\$"
}

3

要在查看整个文件时突出显示模式,h可以这样做。

另外,它对不同的图案使用不同的颜色。

cat FILE | h 'PAT1' 'PAT2' ...

您还可以通过管道h传输到的输出,以less -R更好地阅读。

要grep并为每种图案使用1种颜色,cxpgrep可能是一个很好的选择。


1

好的,这是一种方法,

wc -l filename

将为您提供行数-说NN,那么您可以

grep -C NN --color=always filename

3
如果您不想先wc,请输入“ -C 2147483647”。在此处使用大量数字似乎不会减慢速度。
barrycarter

1

这是一个使用Awk的gsub函数将您要搜索的文本替换为正确的转义序列以将其显示为亮红色的shell脚本:

#! /bin/bash
awk -vstr=$1 'BEGIN{repltext=sprintf("%c[1;31;40m&%c[0m", 0x1B,0x1B);}{gsub(str,repltext); print}' $2

像这样使用它:

$ ./cgrep pattern [file]

不幸的是,它没有grep的所有功能。

有关更多信息,请参阅Linux Journal中的文章“ So You Like Color ”。


1

另一个答案提到了grep的-Cn开关,其中包括n行上下文。有时,我会使用n = 99进行此操作,这是一种快速而又肮脏的方法,当egrep模式看起来过于杂乱,或者当我在未安装rcg的计算机上时,至少获得全屏的上下文和/或ccze。

我最近发现ccze这是一种功能更强大的着色剂。我唯一的抱怨是它是面向屏幕的(例如less,出于这个原因我从不使用),除非您为“原始ANSI”输出指定-A开关。

rcg上面提到的+1 。仍然是我的最爱,因为在别名中自定义非常简单。这样的东西通常在我的〜/ .bashrc中:

别名tailc ='tail -f / my / app / log / file | rcg发送“ BOLD GREEN”收到“ CYAN”错误“ RED”'


1

另一种肮脏的方式:

grep -A80 -B80 --color FIND_THIS IN_FILE

我做了一个

alias grepa='grep -A80 -B80 --color'

在bashrc中。


1
如果您要找的东西不存在,这是有问题的。说出错误,在这种情况下您将一无所获。
Paul Rubel 2013年


0

如果你想强调几个模式用不同的颜色看这个 bash脚本。

基本用法:

echo warn error debug info 10 nil | colog

您可以在运行时更改图案和颜色,同时按一个键,然后按Enter键。


0

我将以下命令用于类似目的:

grep -C 100 searchtext file

这将表示grep在突出显示的搜索文本之前和之后打印100 * 2行上下文。


0

这是我的方法,灵感来自@kepkin的解决方案:

# Adds ANSI colors to matched terms, similar to grep --color but without
# filtering unmatched lines. Example:
#   noisy_command | highlight ERROR INFO
#
# Each argument is passed into sed as a matching pattern and matches are
# colored. Multiple arguments will use separate colors.
#
# Inspired by https://stackoverflow.com/a/25357856
highlight() {
  # color cycles from 0-5, (shifted 31-36), i.e. r,g,y,b,m,c
  local color=0 patterns=()
  for term in "$@"; do
    patterns+=("$(printf 's|%s|\e[%sm\\0\e[0m|g' "${term//|/\\|}" "$(( color+31 ))")")
    color=$(( (color+1) % 6 ))
  done
  sed -f <(printf '%s\n' "${patterns[@]}")
}

这接受多个参数(但不允许您自定义颜色)。例:

$ noisy_command | highlight ERROR WARN

-1

有什么办法可以告诉grep打印正在读取的每一行,而不管是否有匹配项?

选件-C999会做的伎俩在没有选项来显示所有上下文行。大多数其他grep变体也支持此功能。但是:1)当没有找到匹配项时,不产生任何输出; 2)此选项对grep的效率产生负面影响:当该-C值较大时,可能必须将许多行临时存储在内存中,以便grep确定上下文的哪几行在发生匹配时显示。请注意,grep实现不加载输入文件,而是读取几行或在输入上方使用滑动窗口。必须将上下文的“之前”部分保存在一个窗口(内存)中,以便在找到匹配项之后稍后输出“之前”的上下文行。

诸如^|PATTERNPATTERN|$或任何空匹配子模式之类的模式[^ -~]?|PATTERN是一个不错的技巧。但是,1)这些模式没有显示突出显示为上下文的不匹配行,2)不能与其他grep选项(例如-F和)结合使用-w

因此,这些方法都不令我满意。我正在使用ugrep,并使用带有选项的增强型grep -y来有效地将所有不匹配的输出显示为颜色突出显示的上下文行。其他类似grep的工具(例如ag和ripgrep)也提供了传递选项。但是ugrep与GNU / BSD grep兼容,并提供了grep选项的超集,例如-y-Q。例如,以下选项-y与结合使用时将显示什么选项-Q(交互式查询UI以输入模式):

ugrep -Q -y FILE ...

为什么在不发表评论的情况下对此予以否决?提及替代grep工具和其他一些答案是很公平的。
Alex RE博士
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.