选择日志文件中两个时间戳之间的所有内容

ach*_*san 5 regular-expression

awk '/10:..:/, /13:..:/' server.log > /tmp/awktmp
Run Code Online (Sandbox Code Playgroud)

我按照有人给我的命令尝试了这个命令。它对我来说可以找到上午 10:00 到下午 13:00 之间的日志,但我不完全理解它。

如果您有一个优雅的解决方案,请告诉我。请记住,远程服务器很小,并且没有高级实用程序。

我在这里不明白的是'/10:..:/, /13:..:/'

  • 我理解10:..意思10是 和:完全匹配 2 位数字。
  • 但另一个是什么:意思呢?

我想正斜杠是用来放置正则表达式的,就像我们在 JavaScript 正则表达式中所做的那样。我对此不是100%确定。

更新1:

时间位于第二列,格式为HH:MM:SS

更新2:

sed -n -e '/8:..:../,/9:..:../p' application.log > /tmp/sedtmp
Run Code Online (Sandbox Code Playgroud)

我尝试了这个,但这也显示了来自 的日志07:57:47

更新3

日志并不总是在每一行中包含时间戳。有些行根本不包含任何时间戳。你是如何克服这个问题的?我愚蠢地使用了 awk,并且错过了所有没有时间价值的行。有办法避免这个问题吗?

这就是我的意思。

2023-08-07 09:20:35 0123456789 INFO  CustomerLogoutResource:95 - Entering logout api.
2023-08-07 09:20:35 0123456789 ERROR AppExceptionMapper:87 - Exception has been thrown by container
2023-08-07 09:20:35 0123456789 ERROR AppExceptionMapper:555 - Unchecked Exception
java.lang.NullPointerException
    at NullPointerExceptionExample.printLength(NullPointerExceptionExample.java:3)
    at NullPointerExceptionExample.main(NullPointerExceptionExample.java:8)
Run Code Online (Sandbox Code Playgroud)

Pau*_*ant 8

该模式/10:..:/匹配数字 10、两个分隔符:以及它们之间的任意两个字符。因此它将匹配一个时间(输入行内的任何位置),例如10:35:22。但它也会匹配包含 的行This10:ZZ:Camels,因此这不是一个很好的测试。

更好的模式可能是/10:[0-5][0-9]:[0-5][0-9]/,它检查分钟和秒是否在 00-59 范围内。但检查时间是否在特定字段中,或者当时是否有空格,或者(包括)接近记录的开头也可能会有所帮助。您可以发布一些示例输入行,以便我们更好地了解需要什么。

用逗号分隔两个模式会在检测到第一个模式时“打开”匹配,而在检测到第二个模式时“关闭”匹配。它将匹配这些事件之间的所有行(包括),即使它们根本不包含日期。

这与单一模式非常不同/1[0-2]:[0-5][0-9]:[0-5][0-9]/,单一模式只匹配 10:00:00 到 12:59:59 之间的各个行,无论它们碰巧是什么顺序。


Sté*_*las 8

如果 10:00 到 11:00 之间没有登录,这种方法无法找到 to 的行,11:00并且如果 13:00 到 14:00 之间没有登录,则将报告之后的所有行(并且至少有10 到 11 之间的一个)。13:0014:00

对于这种事情,最好对时间与边界进行词法比较。

例如,如果时间在第三个字段中:

awk '$3 >= "10:00:00" && $3 < "13:00:00"'
Run Code Online (Sandbox Code Playgroud)

如果您不知道时间在队列中的哪个位置,您可以这样做:

perl -lne 'print if /\b\d\d:\d\d:\d\d\b/ &&
                      $& ge "10:00:00" &&
                      $& lt "13:00:00"'
Run Code Online (Sandbox Code Playgroud)

或者:

LC_ALL=C awk 'match($0, /[0-2][0-9]:[0-5][0-9]:[0-5][0-9]/) && \
                (t = substr($0, RSTART, 8)) >= "10:00:00" && \
                t < "13:00:00"'
Run Code Online (Sandbox Code Playgroud)

这些报告了在该范围内具有时间戳的行。如果带有时间戳的行之间有没有时间戳的行,并且您希望报告它们,则可以使用beginning-condition, end-condition {action}问题中的方法,但再次使用比较而不是正则表达式匹配,或者手动进行状态切换,以继续排除上限:

LC_ALL=C awk -v beg=10:00:00 -v end=13:00:00 '
  match($0, /[0-2][0-9]:[0-5][0-9]:[0-5][0-9]/) {
    t = substr($0, RSTART, 8)
    if (t >= end) selected = 0
    else if (t >= beg) selected = 1
  }
  selected'
Run Code Online (Sandbox Code Playgroud)