我想知道通用unix工具集中是否有一个程序,例如grep,而不是过滤包含字符串的行,而是仅输出相同的输入,而是突出显示或着色所选的字符串。

正在考虑自己做(应该很简单),但是也许它已经作为unix命令存在。

我打算用它来监视日志,所以我会做这样的事情:

tail -f logfile.log | highlight "error"


通常,当我监视日志时,我需要找到一个特定的字符串,但是我还需要知道在字符串之前和之后写的内容,因此有时过滤是还不够。

是否存在类似的东西?

感谢

评论

几乎在这里回答:stackoverflow.com/questions/981601/…

这对我来说似乎是题外话,因为它不要求提供应用程序。当然最好在unix.stackexchange.com上问一下

#1 楼

使用基本的grep命令,这是一个有趣的技巧。它包括使用两个过滤器:您要应用的一个过滤器和一个匹配所有行但不产生高光的虚拟过滤器。此虚拟匹配项可以是^(行的开头)或$(行的结尾)。

grep "^\|text" --color='always' file


grep -E "^|text" --color='always' file


查看示例:

$ cat a
hello this is 
some text i wanted
to share with you
$ grep "^\|text" --color='always' a
hello this is 
some text i wanted     # "text" is highlighted
to share with you


评论


看起来您甚至都不需要^或$,而“ | text”也可以。

–音乐爱好者
2014年12月5日在19:07

#2 楼

有一个名为ack的工具。您可以在http://beyondgrep.com上找到它,它确实是grep以外的工具。它最常见的用途是填补find . -name "*.java" --print | xargs grep clazz等角色。因为我们一直都这样做。

只需ack clazz,您就会得到输出。搜索适当的文件(不必费心尝试grep二进制文件),并提供不错的颜色输出。

如果将其与--passthru选项一起使用,它将打印整个输入流,突出显示匹配的区域彩色。


--passthru打印所有行,无论是否匹配


如文档所述,如果文件中使用-,它将取STDIN:


如果指定了任何文件或目录,则
仅检查那些文件和目录。 ack也可以搜索STDIN,但是只有在未指定文件或目录参数的情况下,
或其中之一是“-”。


因此,请原谅cat滥用(以及双关语-见下文),您可以使用它:

$ cat file | ack --passthru pattern
$ cat file | ack --passthru pattern -


这将获取管道的输出,并将其通过ack发送,将进行打印突出显示该模式的所有行(带有--passthru)。

这正是您所需要的工具(还有更多)。它是许多软件包管理器的标准软件包。请参阅http://beyondgrep.com/install/了解您的收藏夹。

_   /|
\'o.O'
=(___)=
   U    ack --thpppt!


(如果您不认识它,那就可以对猫开帐单,尽管图像搜索可能会也有帮助-不要单击Miley Cyrus套装)

评论


Ack是一个很棒的工具,但是如何仅突出显示搜索模式就可以打印整个输入呢?正如您所解释的,它通常用作目标grep -R的一种形式,我不知道它如何对OP有所帮助。

– terdon
2014年12月6日12:11



@terdon --passthru选项将打印所有行并突出显示感兴趣的模式。同样,对于使用STDIN的用户,可以将连字符用作文件“名称”,或者根本不使用文件参数。

–user450
2014年12月6日18:41

我知道,这很有意义。既然您说过它就像grep一样,那么我假设它只会打印匹配的行。

– terdon
2014年12月7日,0:28

@terdon,其默认模式为grepy。尽管人们已经指出了其他选择,但是可以欺骗grep打印所有行并突出显示感兴趣的文本。 ack不需要那么做-它是标准选项之一。并感谢您所做的澄清编辑。

–user450
2014-12-7 0:31



#3 楼

您可以使用grep -C标志,该标志给出n行上下文,例如grep -C 3将在比赛前后打印3行。

如果要定期突出显示给定的字符串,例如,-B-A。特定的日志格式,使用带有自定义词法分析器的python pygmentize可能值得,因为它是基于正则表达式的,您会惊奇地发现它是如此简单。后者还具有跨平台的优点,尽管某些终端的颜色效果不佳。

#4 楼

我编写了一个小脚本,该脚本将为您提供的任何字符串着色:

#!/usr/bin/env perl
use Getopt::Std;
use strict;
use Term::ANSIColor; 

my %opts;
getopts('hic:l:',\%opts);
    if ($opts{h}){
      print<<EoF; 
Use -l to specify the pattern(s) to highlight. To specify more than one 
pattern use commas. 

-l : A Perl regular expression to be colored. Multiple expressions can be
     passed as comma separated values: -l foo,bar,baz
-i : makes the search case sensitive
-c : comma separated list of colors;

EoF
      exit(0);
    }

my $case_sensitive=$opts{i}||undef;
my @color=('bold red','bold blue', 'bold yellow', 'bold green', 
           'bold magenta', 'bold cyan', 'yellow on_magenta', 
           'bright_white on_red', 'bright_yellow on_red', 'white on_black');
if ($opts{c}) {
   @color=split(/,/,$opts{c});
}
my @patterns;
if($opts{l}){
     @patterns=split(/,/,$opts{l});
}
else{
    $patterns[0]='\*';
}

# Setting $| to non-zero forces a flush right away and after 
# every write or print on the currently selected output channel. 
$|=1;

while (my $line=<>) 
{ 
    for (my $c=0; $c<=$#patterns; $c++){
    if($case_sensitive){
        if($line=~/$patterns[$c]/){
           $line=~s/($patterns[$c])/color("$color[$c]")..color("reset")/ge;
        }
    }
    else{
        if($line=~/$patterns[$c]/i){
          $line=~s/($patterns[$c])/color("$color[$c]")..color("reset")/ige;
        }
      }
    }
    print STDOUT $line;
}


如果将其另存为color并位于$PATH的目录中并进行制作可执行文件(chmod +x /usr/bin/color),您可以像这样为匹配的样式上色:

echo -e "foo\nbar\nbaz\nbib" | color -l foo,bib 


将产生:



如所写,脚本为10种不同的模式提供了预定义的颜色,因此像上面的示例中那样,以逗号分隔的列表形式给每个匹配的模式以不同的颜色进行着色。

#5 楼

我是Paolo Antinori的hhighlighter的粉丝。 https://github.com/paoloantinori/hhighlighter

该命令的一个优点是可以突出显示多达10个具有独特颜色的单词。
只需将命令的输出通过管道传递给h加上突出显示的单词。

例如tail -f /var/log/somelog.log | h "ERROR"
将产生:



他的站点中的一些示例:



#6 楼

我前段时间编写了一个程序来执行此操作。我称之为cgrep(用于彩色grep)。

您可以通过将代码部分从此处复制到一个空文件中来下载它:http://wiki.tcl.tk/38096

然后将文件设为可执行文件并将其复制到常规bin目录之一。

它是用tcl编写的,因此您需要安装tcl(8.5及更高版本)。但是大多数Linux发行版仍然会安装tcl,因为许多软件都在使用tcl(gitk,内核配置,expect等)。

着色的语法很简单:regex option option ..。您可以根据需要使用任意多个正则表达式。这是一个示例,该错误将红色错误标记为黄色,将警告颜色标记为黄色:

tail -f logfile | cgrep '^.*WARNING.*$' -fg yellow '^.*ERROR.*$' -fg red -bg yellow


#7 楼

我认为最简单的方法是这样的:

tail -f logfile.log | grep -e 'error' -e '**'




无需安装任何东西。

#8 楼

好吧,我正在运行Fedora 21,如果键入

grep -E \|kk rs.c


,它将输出文件“ rs.c”的全部内容,同时突出显示“ kk”的出现“。

评论


这基本上与arielCo的答案相同。

– Izzy♦
2014年12月5日20:26

@Izzy:虽然语法较短,所以我想说它有资格作为其他有效答案。

–尼古拉斯·拉乌尔(Nicolas Raoul)♦
16 Mar 16 '16 at 5:58

@NicolasRaoul这就是为什么我当时只留下评论的原因(但没有举报)。基本上,我希望海报扩大一点;)

– Izzy♦
16 Mar 16 '16 at 7:46

#9 楼

您可以使用此命令

grep --color --context=1000


或更短

grep --col -1000


explainshell.com-grep --color- -context

#10 楼

一个简单的技巧就是匹配一个空字符串或一行的开头。要么导致所有行的零长度匹配:

grep --color -e 'REGEXP' -e ''
grep --color -e 'REGEXP' -e ^


或(扩展的regexp语法):

grep --color -E 'REGEXP|'
egrep --color 'REGEXP|'


评论


第一个变体也不会过滤REGEX的输出吗?我只是尝试过,而且确实如此。因此,这与要求不符(仅突出显示,不过滤)。但是第二个变量确实可以执行OP所要求的(已验证;)。

– Izzy♦
2014年12月5日18:46

@Izzy:对不起,我有错字。谢谢!

– ArielCo
2014年12月5日在22:28

是的,现在这很有意义:)过滤REGEX(突出显示该术语)和“无”(即“无处不在”)。我是否可以建议您包括这个小解释(太清楚了它的作用),然后我们删除我们的注释(以进行清理)?谢谢!同时从我+1 :)

– Izzy♦
2014年12月5日22:51

可以,但是Fedorqui在上面给出了基本相同的答案(我想我发布我的时候没有看到它)。

– ArielCo
2014年12月6日在2:30

必须承认我也没有看到……(提示:这里没有“之上”或“之下”,因为答案的顺序取决于您设置的过滤器;)

– Izzy♦
2014年12月6日13:14

#11 楼

使用less。通过/找到的搜索字符串是一个正则表达式,并且出现的内容将突出显示。

#12 楼

在我的.bashrc中,我具有此功能。我将其命名为cgrep,但在这里给它起一个更恰当的名称。

highlight() { grep -E --color "^|"; }


例如,我发现这对于拖尾日志很有用,我想突出显示一个关键字,但可以看到所有情况。

tail -f /var/log/SOMELOG | highlight KEYWORD


评论


到期信用:我得到了“ ^ |” @fedorqui的选定答案中得到的想法。谢谢 :)

– Simesy
18年5月22日在23:33

#13 楼

您可以将输出通过管道传递到:

sed "s/\([Ee][Rr][Rr][Oo][Rr]\)/`tput rev``tput rmso`/"


这里我使用的正则表达式将匹配“ error”,“ ERROR”,“ ErRoR”等。所有32种可能的变体。

#14 楼

我在~/.zshrc中定义了以下函数:

hl () {
    sed s//$'\e[1;31m'\&$'\e[0;m'/
}


tail -f logfile.log | hl "error"一起使用。它将在突出显示的单词之前添加浅红色的转义序列,并在单词之后将其重置为无颜色。您可以在此处找到其他颜色代码:http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html