1

我正在尝试 grep 过去 24 小时内的条目的日志文件。我想出了以下命令:

grep "$(date +%F\ '%k')"\|"$(date +%F --date='yesterday')\ [$(date +%k)-23]" /path/to/log/file

我知道正则表达式可以在 grep 中使用,但对正则表达式不是很熟悉。你看,我正在寻找今天或昨天在当前时间或更高时间之间的任何东西。这不起作用,我猜是由于我试图在 grep 的正则表达式中将命令作为变量传递的方式。我也不反对将 awk 与 awk 一起使用,我想出了以下内容,但它没有正确检查变量:

t=$(date +%F) | y=$(date +%F --date='yesterday') | hr=$(date +%k) | awk '{ if ($1=$t || $1=$y && $2>=$hr) { print $0 }}' /path/to/log/file

我会假设 systime 可以与 awk 而不是设置变量一起使用,但我对 systime 一点也不熟悉。任何命令的任何建议将不胜感激!哦,这是日志格式:

2012-12-26 16:33:16 SMTP connection from [127.0.0.1]:46864 (TCP/IP connection count = 1)
2012-12-26 16:33:16 SMTP connection from (localhost) [127.0.0.1]:46864 closed by QUIT
2012-12-26 16:38:19 SMTP connection from [127.0.0.1]:48451 (TCP/IP connection count = 1)
2012-12-26 16:38:21 SMTP connection from [127.0.0.1]:48451 closed by QUIT
2012-12-26 16:38:21 SMTP connection from [127.0.0.1]:48860 (TCP/IP connection count = 1)
4

1 回答 1

1

这是使用GNU awk. 像这样运行:

awk -f script.awk file

内容script.awk

BEGIN {
    time = systime()
}

{ 
    spec = $1 " " $2
    gsub(/[-:]/, " ", spec)
}

time - mktime(spec) < 86400

或者,这是单线:

awk 'BEGIN { t = systime() } { s = $1 " " $2; gsub(/[-:]/, " ", s) } t - mktime(s) < 86400' file

此外,传递 shell 变量的正确方法awk是使用-v标志。我对您的awk命令进行了一些调整以向您展示我的意思,但我建议不要这样做:

awk -v t="$(date +%F)" -v y="$(date +%F --date='yesterday')" -v hr="$(date +%k)" '$1==t || $1==y && $2>=hr' file

解释:

所以在awk开始处理文件之前,首先处理BEGIN块。在这个块中,我们创建了一个名为time/的变量t,并使用该systime()函数进行设置。systime()简单地将当前时间作为系统纪元以来的秒数返回。然后,对于日志文件中的每一行,将创建另一个名为/的awk变量,并将其设置为由单个空格分隔的第一个和第二个字段。此外,其他字符喜欢并且需要全局替换为空格才能使函数正常工作,并且使用完成specs-:mktime()gsub(). 然后只需一点数学即可测试日志文件中的日期时间是否在过去 24 小时内(或恰好 86400 秒)。如果测试为真,则打印该行。也许额外阅读会有所帮助,请参阅Time FunctionsString Manipulation Functions。HTH。

于 2012-12-27T00:01:09.043 回答