grep命令查找小于一个数字的前一个单词

我需要一个grep命令的帮助:

grep match-word tomcat-0.log.* | grep "TOMCAT BENCH" | grep -v Normal 

目前的输出是类似于:

 tomcat-0.log:TOMCAT BENCH: match_word random-text 1420 elapsed Thu 2016-09-22 06:31:04:928 PDT <SessionID: id> <RequestID: reqId> 

我想修改这个只显示那些经过值大于3000的数字的行

elapsed的字总是存在的,数字是elapsed的字。

你可以修改grep命令来过滤前面的单词并将其与数字进行比较吗?

正如所要求的,这是一个所有它的蛮力荣耀的所有grep解决方案:

 ... | grep -E "([1-9][0-9]{4,}|3[0-9]{2}[1-9]|3[0-9][1-9]0|[4-9][0-9]{3}) elapsed" 

让我们通过这个解决方案:

  • [1-9][0-9]{4,}匹配任何大于9999的数字。基本上,它证实我们有一个数字字符串,数字在ten thousands place, 100 thousands place, ...或高于0。
    例如, 12000匹配,但是02000不匹配。
  • 3[0-9]{2}[1-9]匹配所有以0结尾的数字3001 - 3999
  • 3[0-9][1-9]0匹配数字,如3010, 3120, 3990, etc. ,以零结尾,但不小于或等于3000
  • [4-9][0-9]{3}匹配大于3999 4位数字

如果前面的模式之一匹配,我们确保它紧跟着字符串“elapsed”,在这种情况下,我们完成了。


PS:记住,我们必须匹配大于 3000的数字。

PPS:请注意,我认为“过去”之前的字符串总是由数字组成; 在检查号码之前,我不确定是否有空间。

PPPS:这是用grep完成的,因为它是解决问题的工具。 我绝不建议grep是一个很好的方法来完成这个任务

PPPPS:由于正在搜索的日志格式,我不希望有处理负数。 因此,我不这样做。 🙂

使用gnu awk可以用一个命令完成:

 awk '/TOMCAT BENCH/ && !/Normal/ && match($0, / ([0-9]+) elapsed /, a) && a[1] > 3000' tomcat-0.log.* 

保持简单,你需要的只是:

 zcat file | awk -F ' *elapsed.*' '/TOMCAT BENCH/ && !/Normal/{n=$1;sub(/.* /,"",n)} n>3000' 

例如,您发布了一行样本输入:

 $ cat file | awk -F ' *elapsed.*' '/TOMCAT BENCH/ && !/Normal/{n=$1;sub(/.* /,"",n)} n>1400' tomcat-0.log:TOMCAT BENCH: match_word random-text 1420 elapsed Thu 2016-09-22 06:31:04:928 PDT <SessionID: id> <RequestID: reqId> 

您可以使用awk命令,如下所示:

 awk '{for(i=1;i<=NF;i++){ if($i == "elapsed") { if ($(i-1) >3000 ) print; } }}' file 

假设您的示例输入文件是

 $ cat file t-0.log:TOMCAT BENCH: match_word random-text 1420 elapsed Thu 2016-09-22 06:31:04:928 PDT <SessionID: id> <RequestID: reqId> t-0.log:TOMCAT BENCH: match_word random-text 5420 elapsed Thu 2016-09-22 06:31:04:928 PDT <SessionID: id> <RequestID: reqId> t-0.log:TOMCAT BENCH: match_word random-text 420 elapsed Thu 2016-09-22 06:31:04:928 PDT <SessionID: id> <RequestID: reqId> t-0.log:TOMCAT BENCH: match_word random-text 3100 elapsed Thu 2016-09-22 06:31:04:928 PDT <SessionID: id> <RequestID: reqId> t-0.log:TOMCAT BENCH: match_word random-text 0 elapsed Thu 2016-09-22 06:31:04:928 PDT <SessionID: id> <RequestID: reqId> t-0.log:TOMCAT BENCH: match_word random-text 6596 elapsed Thu 2016-09-22 06:31:04:928 PDT <SessionID: id> <RequestID: reqId> 

运行awk命令产生

 $ awk '{for(i=1;i<=NF;i++){ if($i == "elapsed") { if ($(i-1) >3000 ) print; } }}' file t-0.log:TOMCAT BENCH: match_word random-text 5420 elapsed Thu 2016-09-22 06:31:04:928 PDT <SessionID: id> <RequestID: reqId> t-0.log:TOMCAT BENCH: match_word random-text 3100 elapsed Thu 2016-09-22 06:31:04:928 PDT <SessionID: id> <RequestID: reqId> t-0.log:TOMCAT BENCH: match_word random-text 6596 elapsed Thu 2016-09-22 06:31:04:928 PDT <SessionID: id> <RequestID: reqId> 

你只需要添加

 | awk 'match($0, / ([0-9]+) elapsed /, a) && a[1] > 3000' 

在命令的最后:

 grep match_word tomcat-0.log.* | grep "TOMCAT BENCH" | grep -v Normal | awk 'match($0, / ([0-9]+) elapsed /, a) && a[1] > 3000' 

使用numgrep

 ... | grep elapsed | numgrep /3000../