awk/sed/grep:打印与字符串匹配的所有行以及这些行后带有制表符的所有行

awk/sed/grep:打印与字符串匹配的所有行以及这些行后带有制表符的所有行

我想从日志文件中提取以特定 UUID 启动的 http 线程的相关数据。日志示例:

2018-09-26 06:34:24,815 INFO  [com.xxx.xxx.xxx] (http-threads-threads - 73244) UUID: 111-222-333-444-555
2018-09-26 06:34:25,224 WARN  [com.xxx.xxx.xxx] (http-threads-threads - 74391) Some log message
2018-09-26 06:34:26,782 INFO  [com.xxx.xxx.xxx] (http-threads-threads - 74399) Some log message
2018-09-26 06:34:26,945 ERROR [com.xxx.xxx.xxx] (http-threads-threads - 73244) Some exception message of the right thread
    at com.xxx.xxx.xxx(someclass.java:114) [somejar.jar:1.0.0]
    at com.xxx.xxx.xxx(someclass.java:65) [somejar.jar:1.0.0]
    at com.xxx.xxx.xxx(someclass.java:85) [classes:]
2018-09-26 06:34:26,950 ERROR [com.xxx.xxx.xxx] (http-threads-threads - 74256) Unauthorized: com.xxx.xxx.xxx: Unauthorized
    at com.xxx.xxx.xxx(someclass.java:39) [somejar.jar:1.0.0]
    at com.xxx.xxx.xxx(someclass.java:49) [somejar.jar:1.0.0]
    at com.xxx.xxx.xxx(someclass.java:45) [somejar.jar:1.0.0]
2018-09-26 06:34:26,952 INFO  [com.xxx.xxx.xxx] (http-threads-threads - 74395) Some log message
2018-09-26 06:34:27,014 WARN  [com.xxx.xxx.xxx] (http-threads-threads - 73244) Some log message of the right thread
2018-09-26 06:34:27,530 INFO  [com.xxx.xxx.xxx] (http-threads-threads - 74365) Some log message

我已经可以使用 grep 和 BASH_REMATCH 搜索 UUID 并提取线程号。知道线程号我可以搜索“http-threads-threads - 73244”。现在我想打印带有该字符串的所有行以及这些行之后的任何最终异常(带有制表符的行)。

我想要这样的输出:

2018-09-26 06:34:24,815 INFO  [com.xxx.xxx.xxx] (http-threads-threads - 73244) UUID: 111-222-333-444-555
2018-09-26 06:34:26,945 ERROR [com.xxx.xxx.xxx] (http-threads-threads - 73244) Some exception message of the right thread
    at com.xxx.xxx.xxx(someclass.java:114) [somejar.jar:1.0.0]
    at com.xxx.xxx.xxx(someclass.java:65) [somejar.jar:1.0.0]
    at com.xxx.xxx.xxx(someclass.java:85) [classes:]
2018-09-26 06:34:27,014 WARN  [com.xxx.xxx.xxx] (http-threads-threads - 73244) Some log message of the right thread

我无法使用,grep -A 3因为匹配后的制表符行数量是可变的。

使用awk '/http\-threads\-threads \- 73244/{print $0; getline}/\tat/{print $0}' log.log还可以打印其他制表符行。

使用awk '/http\-threads\-threads \- 73244/{a=1;print}/(2[0-9][0-9][0-9]\-[0-1]\-[0-9])/{a=0}' log.log根本不会打印制表符行。

一个完美的解决方案还可以去掉之前额外的“grep”和“BASH_REMATCH”并使用UUID,但我完全可以接受将线程号作为“输入”的解决方案。

有人有解决方案吗?

答案1

以下 AWK 脚本匹配 UUID 并输出您感兴趣的相应行:

#!/usr/bin/awk -f

/UUID: 111-222-333-444-555/ {
    tid = substr($7, 1, length($7) - 1)
}

/^[^\t].*http-threads-threads/ {
    if (substr($7, 1, length($7) -1) == tid) {
        matched = 1
        print
    } else {
        matched = 0
    }
}

/^\t/ && matched

第一个块匹配 UUID 并存储相应的线程标识符。

第二个块匹配不以制表符开头的行,包含“http-threads-threads”。如果第七个字段与线程标识符匹配,则脚本会指出我们位于匹配的块中,并打印当前行;否则,脚本会指出我们不在匹配块中。

当我们位于匹配块中时,第三个块匹配以制表符开头的行,并打印它们(打印当前行是默认操作)。

相关内容