使用 Awk 和 Grep 在日志文件中查找两个时间之间的行

Use Awk and Grep to find lines between two time in a log file

我正在搜索一个日志文件,看它是否包含两个不同时间之间的特定字符串。即如果 foo 存在于以 2016-11-10 06:45:002016-11-10 10:45:00 的时间戳开头的行之间 threshold 变量设置之间的时间,例如 240 将是 4 小时。

current="$(date "+%Y-%m-%d %H:%M:%S")"
threshold=240
dt_format="+%Y-%m-%d %H:%M:%S"
from="$(date -d "$threshold minutes ago" "$dt_format")"

if awk '[=10=] >= "$from" && [=10=] <= "$current"' /path/file.log | grep "foo"
then
   exit 0
else
   exit 1
fi

但是我不确定为什么,但是当我在 if 语句的命令行中传递 $from$current 时,它实际上并没有读取它。就好像我传递的是垃圾,所以它没有比较正确的日期,并且 return 所有行并退出 0。

但是如果我在 if 语句中手动输入日期,即 2016-11-10 06:45:00 作为 from2016-11-10 10:45:00 作为 current 那么它 returns 是这两个日期之间的正确行,然后我可以使用 grep 检查这些行是否包含 foo.

我真的不明白为什么我的代码不起作用,而且我不能手动输入日期,因为我需要能够根据我的需要通过更改 threshold变量。

2016-11-10 06:45:00 是时间戳在我的日志中的格式,从每行的开头开始。

谢谢。

您正在尝试 bash 扩展变量单引号... 运行 s="string"; echo '$s' 您会明白我的意思。

所以这个 '[=11=] >= "$from" && [=11=] <= "$current"' 字面意思是那些确切的字符。可能不是你想要的。

"But that's the argument to awk"... 正确所以 awk 知道如何处理 $0 和 $1,所以 awk 正确地扩展了它们。但是你期望 awk 得到 '[=12=] >= "some_time" && [=12=] <= "Some_other_time"' 但它没有!

因此,将变量传递给 awk 的方式是 some_variable="world"; awk -v my_variable=$some_variable 'BEGIN{print "hello", my_variable}'

所以你应该 if awk -v f="$from" -v c="$current" '[=14=] >= f && [=14=] <= c' /path/file.log | grep "foo"

查看 http://www.catonmat.net/blog/ten-awk-tips-tricks-and-pitfalls/ 这篇文章实际上对使用 awk 可以做的巧妙的事情有一些很好的见解。您 可能 能够使用此处的 "split file on patterns" 来减少您使用的命令数量,但无论哪种方式,您都会学到一些关于 awk 的东西。