【问题标题】:grep using variable and regexgrep 使用变量和正则表达式
【发布时间】:2023-03-04 04:30:02
【问题描述】:

我正在尝试 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)

【问题讨论】:

  • 我们可以查看您的日志文件吗?漂亮吗?
  • 这里是日志的前几行: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 来自 (localhost) [127.0.0.1]:46864 的 SMTP 连接由 QUIT 关闭 2012-12-26 16:38:19 来自 [127.0.0.1]:48451 的 SMTP 连接(TCP/IP 连接数 = 1) 2012-12-26 16:38:21 来自 [127.0.0.1]:48451 的 SMTP 连接被 QUIT 关闭 2012-12-26 16:38:21 来自 [127.0.0.1]:48860 的 SMTP 连接(TCP/IP 连接计数 = 1)

标签: linux date ssh awk grep


【解决方案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 将创建另一个名为 spec / s 的变量,并将其设置为由单个空格分隔的第一个和第二个字段。此外,-: 等其他字符需要全局替换为空格,mktime() 函数才能正常工作,并且使用 gsub() 完成此操作。然后只需一点数学即可测试日志文件中的日期时间是否在过去 24 小时内(或恰好 86400 秒)。如果测试为真,则打印该行。也许多读一点会有所帮助,请参阅 Time FunctionsString Manipulation Functions。 HTH。

【讨论】:

  • 史蒂夫,非常感谢你救了你一命。这完美地工作。你介意解释一下单线是如何工作的吗?看起来你正在用当前时间设置 t 变量,我不太确定第二个字符串在做什么,然后第三个字符串似乎只是在说匹配匹配最后一天的所有内容。您能否确认或否认这一点并解释中间部分,不胜感激xd
  • @mr.pribesh:你是对的 - t 变量被设置为当前时间,最后一个表达式是测试日期时间是否在过去 24 小时内发生。 “中间位”只是将变量spec/s 格式化为mktime() 可以理解的字符串(即格式必须严格:“YYYY MM DD HH MM SS”)。请在上面的链接中查看mktime() 的条目——它应该可以解决问题。 HTH。
  • 史蒂夫,再次非常感谢你。我希望 man 文档这么清楚。非常感谢您的时间和帮助!
猜你喜欢
  • 1970-01-01
  • 2013-08-11
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多