246

我正在传递一个正则表达式模式列表grep来检查系统日志文件。它们通常匹配 IP 地址和日志条目;

grep "1\.2\.3\.4.*Has exploded" syslog.log

它只是一个模式列表,就像"1\.2\.3\.4.*Has exploded"我正在传递的部分一样,在一个循环中,所以我不能传递“-v”。

我很困惑试图与上述相反,并且不匹配具有特定 IP 地址和错误的行,因此“!1.2.3.4.*已爆炸”将匹配 1.2.3.4 以外的任何内容的系统日志行,告诉我它已经爆炸. 我必须能够包含一个不匹配的 IP。

我在 StackOverflow 上看到过各种类似的帖子。但是,他们使用我似乎无法使用的正则表达式模式grep。任何人都可以提供一个工作示例grep吗?

更新: 这发生在这样的脚本中;

patterns[1]="1\.2\.3\.4.*Has exploded"
patterns[2]="5\.6\.7\.8.*Has died"
patterns[3]="\!9\.10\.11\.12.*Has exploded"

for i in {1..3}
do
 grep "${patterns[$i]}" logfile.log
done
4

3 回答 3

467

grep匹配,grep -v做相反的事情。如果您需要“匹配 A 但不匹配 B”,通常使用管道:

grep "${PATT}" file | grep -v "${NOTPATT}"
于 2012-05-02T10:10:13.380 回答
19
(?<!1\.2\.3\.4).*Has exploded

您需要使用 -P 运行它以获得否定的lookbehind(Perl 正则表达式),因此命令是:

grep -P '(?<!1\.2\.3\.4).*Has exploded' test.log

试试这个。如果它前面是 ,它使用否定的lookbehind 忽略该行1.2.3.4。希望有帮助!

于 2012-05-02T10:12:18.077 回答
2
patterns[1]="1\.2\.3\.4.*Has exploded"
patterns[2]="5\.6\.7\.8.*Has died"
patterns[3]="\!9\.10\.11\.12.*Has exploded"

for i in {1..3}
 do
grep "${patterns[$i]}" logfile.log
done

应该是一样的

egrep "(1\.2\.3\.4.*Has exploded|5\.6\.7\.8.*Has died)" logfile.log | egrep -v "9\.10\.11\.12.*Has exploded"    
于 2013-09-05T13:55:14.233 回答