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

选择日志文件中两个时间戳之间的所有内容
awk '/10:..:/, /13:..:/' server.log > /tmp/awktmp

我按照有人给我的命令尝试了这个命令。它对我来说可以找到上午 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

我尝试了这个,但这也显示了来自 的日志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)

答案1

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

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

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

awk '$3 >= "10:00:00" && $3 < "13:00:00"'

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

perl -lne 'print if /\b\d\d:\d\d:\d\d\b/ &&
                      $& ge "10:00:00" &&
                      $& lt "13:00:00"'

或者:

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"'

这些报告了在该范围内具有时间戳的行。如果带有时间戳的行之间有没有时间戳的行,并且您希望报告它们,则可以使用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'

答案2

该模式/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 之间的各个行,无论它们碰巧是什么顺序。

答案3

awk 模式:

/regA/,/regB/

从匹配 regA 的第一行到匹配 regB 的第一行都为 true。和往常一样,当某些内容与表达式匹配时:如果表达式后面没有任何内容{ actions }来精确说明匹配时要执行的操作,则默认操作是:打印表达式为 true 的行。

现在他们选择了:

/10:..:/, /13:..:/

更加确定您匹配 10:mm:ss 而不是 hh:10:ss。 (他们通过假设任何时间引用都是 : hh:mm:ss 来做到这一点,并且小时之前没有“:”......这并不总是正确的,具体取决于所使用的日期格式。正如所说在评论中,它也可以匹配其他东西。

如果您知道行的开头始终是:

YYYY-MM-DDThh:mm:ss+hh:mm 
# For exemple:
# 2023-07-17T11:14:02+02:00 , which is following internationnal recommendations
# of displaying date and time (and timezone)

您可以更紧密地匹配:

/^2023-07-17T10:/,/^2023-07-17T13:/

并确保仅从行的开头 (^) 开始匹配,而不是从行中可能出现的任何位置进行匹配。

答案4

这是一个可能的解决方案,它选择日志文件中两个时间戳之间的日志。此脚本假定日志文件具有以空格分隔的列,并且第二列包含格式为 的时间戳HH:MM:SS可能不是最优雅的,但至少是清晰的。

awk -F" " '$2 >= "09:00:00" && $2 <= "12:00:00"' server.log
  • -F" "将字段分隔符设置为空格字符。
  • $2指输入文件每行中的第二个字段(在这种情况下,字段之间用空格分隔)。
  • >= "09:00:00"检查第二个字段的值是否大于或等于“09:00:00”。
  • &&组合条件的逻辑运算符。意思是“和”
  • $2 <= "12:00:00"检查第二个字段的值是否小于或等于“12:00:00”。
  • sever.log是你的输入文件

方案验证

对于server.log看起来像这样的:

2023-07-18 08:55:32 - Log entry 1
2023-07-18 09:10:15 - Log entry 2
2023-07-18 10:30:47 - Log entry 3
2023-07-18 11:45:02 - Log entry 4
2023-07-18 12:05:21 - Log entry 5
2023-07-18 13:20:33 - Log entry 6

输出:

[get@me test]$ awk -F" " '$2 >= "09:00:00" && $2 <= "12:00:00"' server.log
2023-07-18 09:10:15 - Log entry 2
2023-07-18 10:30:47 - Log entry 3
2023-07-18 11:45:02 - Log entry 4

相关内容