我正在尝试对过去 24 小时内的条目进行 grep 日志文件。我想出了以下命令:
grep "$(date +%F\ '%k')"\|"$(date +%F --date='yesterday')\ [$(date +%k)-23]" /path/to/log/file
我知道 grep 中可以使用正则表达式,但对 regex 不是很熟悉。你看我正在寻找今天或昨天在当前时间或更晚时间之间的任何内容。这是行不通的,我猜是由于我试图在 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)
最佳答案
这是使用 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
block 。在这个 block 中,我们创建了一个名为 time
/t
的变量,这是使用 systime()
函数设置的。 systime()
简单地返回当前时间作为自系统纪元以来的秒数。然后,对于日志文件中的每一行,awk
将创建另一个名为 spec
/s
的变量,并将其设置为第一个和第二个字段由一个空格分隔。此外,-
和 :
等其他字符需要全局替换为空格,以便 mktime()
函数正常工作,这使用 gsub()
。然后测试日志文件中的日期时间是否在最近 24 小时内(或恰好 86400 秒)只是一个小数学。如果测试为真,将打印该行。也许多读一点会有帮助,请参阅 Time Functions和 String Manipulation Functions . HTH.
关于linux - grep 使用变量和正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14046715/