grep如果下一个X行不包含特定字符串

时间:2018-04-04 18:12:33

标签: linux awk grep

我创建了一个每隔几分钟运行一次的cron作业并执行" grep"在日志文件中以查找警告。
我想在相关警告开始的6行之后忽略一个包含特定字符串的警告 挑战在于每个警告由几条单独的线而不是一条长线组成 有没有推荐的方法呢?

记录例如:

2018-04-04 05:15:13,576 [housekeeper] DEBUG not-relevant...
2018-04-04 05:16:19,226 [housekeeper] DEBUG not-relevant...
2018-04-04 05:45:28,383 [housekeeper] WARN  com.zaxxer.hikari.pool.ProxyLeakTask - Connection leak detection triggered for com.mysql.jdbc.JDBC4Connection@2f350071, stack trace follows
java.lang.Exception: Apparent connection leak detected
    at com.sql.HikariConnectionPool.getConnection(java:)
    at com.DBConnection.getConn(java:)
    at com.DBConnection.getConn(java:)
    at com.EAgent.checkER(aaa.java:)
    at com.EAgent$EExecuter.run(aaa.java:)
2018-04-04 05:55:54,425 [housekeeper] DEBUG not-relevant...
2018-04-04 05:58:16,814 [DBPool housekeeper] WARN  com.zaxxer.hikari.pool.ProxyLeakTask - Connection leak detection triggered for com.mysql.jdbc.JDBC4Connection@45df031, stack trace follows
java.lang.Exception: Apparent connection leak detected
    at com.HikariConnectionPool.getConnection(HikariConnectionPool.java:)
    at com.DBConnection.getConn(aaa.java:)
    at com.DBConnection.getConn(aaa.java:)
    at com.m.checkUC(aaa.java:)
    at com.m.run(aaa.java:)
    at java.c.ThreadPoolExecutor.runWorker(aaa.java:)
    at java.c.ThreadPoolExecutor$Worker.run(aaa.java:)
    at java.lang.Thread.run(aaa.java:)

我的grep:grep -A6 -ne 'Connection leak detection' -ne WARN myfile.log

我想忽略包含" EAgent"的所有警告,以便输出为:

2018-04-04 05:58:16,814 [DBPool housekeeper] WARN  com.zaxxer.hikari.pool.ProxyLeakTask - Connection leak detection triggered for com.mysql.jdbc.JDBC4Connection@45df031, stack trace follows
java.lang.Exception: Apparent connection leak detected
    at com.HikariConnectionPool.getConnection(HikariConnectionPool.java:)
    at com.DBConnection.getConn(aaa.java:)
    at com.DBConnection.getConn(aaa.java:)
    at com.m.checkUC(aaa.java:)
    at com.m.run(aaa.java:)
    at java.c.ThreadPoolExecutor.runWorker(aaa.java:)
    at java.c.ThreadPoolExecutor$Worker.run(aaa.java:)
    at java.lang.Thread.run(aaa.java:)

2 个答案:

答案 0 :(得分:2)

$ cat tst.awk
/^[0-9]/ { prt() }
{ rec = rec $0 ORS }
END { prt() }
function prt() {
    if ( (rec ~ /WARN/) && (rec !~ /EAgent/) ) {
        printf "%s", rec
    }
    rec = ""
}

$ awk -f tst.awk file
2018-04-04 05:58:16,814 [DBPool housekeeper] WARN  com.zaxxer.hikari.pool.ProxyLeakTask - Connection leak detection triggered for com.mysql.jdbc.JDBC4Connection@45df031, stack trace follows
java.lang.Exception: Apparent connection leak detected
    at com.HikariConnectionPool.getConnection(HikariConnectionPool.java:)
    at com.DBConnection.getConn(aaa.java:)
    at com.DBConnection.getConn(aaa.java:)
    at com.m.checkUC(aaa.java:)
    at com.m.run(aaa.java:)
    at java.c.ThreadPoolExecutor.runWorker(aaa.java:)
    at java.c.ThreadPoolExecutor$Worker.run(aaa.java:)
    at java.lang.Thread.run(aaa.java:)

如果执行速度有问题,这应该稍快一点:

/^[0-9]/ {
    if (inWarn) {
        prt()
    }
    inWarn = /WARN/
}
inWarn { rec = rec $0 ORS }
END { if (inWarn) prt() }
function prt() {
    if ( rec !~ /EAgent/ ) {
        printf "%s", rec
    }
    rec = ""
}

答案 1 :(得分:0)

您可以尝试关注awk并告诉我这是否对您有所帮助?

awk '/^[0-9]+/{if(val && !non_flag){print val};non_flag=val=""} /EAgent/ || /DEBUG not-relevant/{non_flag=1} {val=val?val ORS $0:$0} END{if(val && !non_flag){print val}}' Input_file

此处也添加非单线形式的解决方案。

awk '
/^[0-9]+/{
   if(val && !non_flag){
      print val};
   non_flag=val=""}
/EAgent/ || /DEBUG not-relevant/{
   non_flag=1}
{
   val=val?val ORS $0:$0
}
END{
   if(val && !non_flag){
      print val}
}
'   Input_file

<强> 说明:

awk '
/^[0-9]+/{                          ##Checking condition here if a line starts with digits then do following.
   if(val && !non_flag){            ##Checking if variable val is NOT NULL and variable non_flag is NULL then do following.
      print val};                   ##Printing variable val here.
   non_flag=val=""}                 ##Nullifying the value of variable non_flag and val here.
/EAgent/ || /DEBUG not-relevant/{   ##Searching for strings EAgent OR DEBUG not-relevent in a line if either of them found do following
   non_flag=1}                      ##Set variable non_flag value to 1 here.
{
   val=val?val ORS $0:$0            ##Creating variable val whose value is current line and it concatenates its own value with it.
}
END{                                ##Starting END block of awk here.
   if(val && !non_flag){            ##Checking condition if variable val is NOT NULL and variable non_flag is NULL then do following.
      print val}                    ##Printing the variable val here.
}
'   Input_file                      ##Mentioning Input_file name here.