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)
该模式/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 之间的各个行,无论它们碰巧是什么顺序。
如果 10:00 到 11:00 之间没有登录,这种方法无法找到 to 的行,11:00
并且如果 13:00 到 14:00 之间没有登录,则将报告之后的所有行(并且至少有10 到 11 之间的一个)。13:00
14: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)