如何在 grep 中排除“DEBUG”而不引发“BUG”

如何在 grep 中排除“DEBUG”而不引发“BUG”

我试图构建一个命令来 grep 常见的错误关键字列表(例如,,,bug occured!),但也需要排除常见关键字(例如标记)而不抛出匹配的行。该命令应该足够强大,可以处理各种源/日志。errorexceptionDEBUG

假设我有这个来源:

$ cat dummy.log 
12345   DEBUG   debug.log abc
!DEBUG
!bug
!debug
DEBUG noop
12345 DEBUG bug occured
please report BUG to me
the filename is critical_bug.log
bug should be fix.
noop
throws error
a stuff
b otherstuff
c otherstuff stuff

该命令将不起作用,因为它排除了包含以下内容的bug行(即12345 DEBUG bug occuredDEBUG

$ cat -v dummy.log | nl | grep -Ei 'bug|stuff|error' | grep -Evi 'DEBUG|otherstuff'
 3  !bug
 7  please report BUG to me
 8  the filename is critical_bug.log
 9  bug should be fix.
11  throws error
12  a stuff

更改管道的顺序也与上面相同:

$ cat -v dummy.log | nl | grep -Evi 'DEBUG|otherstuff' | grep -Ei 'bug|stuff|error'
 3  !bug
 7  please report BUG to me
 8  the filename is critical_bug.log
 9  bug should be fix.
11  throws error
12  a stuff

^尝试在 grep 中使用([更新]错误的,^不用于排除),但它包含了其中DEBUG noop不包含的内容bug(注意:所有过滤器都应该不区分大小写,例如我想接受BUG occured!并排除debug.log):

 $ cat -v dummy.log | nl | grep -Ei 'bug|stuff|error|^DEBUG|^otherstuff'
 1  12345   DEBUG   debug.log abc
 2  !DEBUG
 3  !bug
 4  !debug
 5  DEBUG noop
 6  12345 DEBUG bug occured
 7  please report BUG to me
 8  the filename is critical_bug.log
 9  bug should be fix.
11  throws error
12  a stuff
13  b otherstuff
14  c otherstuff stuff

debug仅当我仅使用时-w(例如the filename is critical_bug.log未能包含),我才能自定义排除:

$ grep -wnEi 'bug|stuff|error' dummy.log 
3:!bug
6:12345 DEBUG bug occured
7:please report BUG to me
9:bug should be fix.
11:throws error
12:a stuff
14:c otherstuff stuff

我的预期输出(注意:我需要保持匹配的颜色和原始行号):

$ grep -wnEi 'bug|stuff|error' dummy.log 
3:!bug
6:12345 DEBUG bug occured
7:please report BUG to me
8:the filename is critical_bug.log
9:bug should be fix.
11:throws error
12:a stuff
14:c otherstuff stuff

是否可以使用此grep命令或替代命令?

答案1

假设GNUgrep(Linux 上的默认设置)你可以使用 PCRE 模式并且消极的回顾:

$ grep -niP '(?<!de)bug|(?<!other)stuff|error' dummy.log 
3:!bug
6:12345 DEBUG bug occured
7:please report BUG to me
8:the filename is critical_bug.log
9:bug should be fix.
11:throws error
12:a stuff
14:c otherstuff stuff

使用的选项是:

-n, --line-number
    Prefix each line of output with the 1-based line number within 
        its input file.

-i, --ignore-case
    Ignore case distinctions in patterns and input data, so that
    characters that differ only in case match each other.

-P, --perl-regexp
    Interpret  PATTERNS  as  Perl-compatible regular expressions (PCREs).
    This option is experimental when combined with the  -z  (--null-data)
    option, and grep -P may warn of unimplemented features.

神奇的事情发生在回溯中。一般格式是(?!<foo)bar,这意味着“匹配bar但是仅有的如果它前面没有foo"。 那么(?<!de)bug将会匹配,bug除非它出现在 后面de,并且除非它出现在 后面,否则(?<!other)stuff将会匹配。stuffother

相关内容