使用 Awk 和 Grep 在日志文件中查找两个时间之间的行
Use Awk and Grep to find lines between two time in a log file
我正在搜索一个日志文件,看它是否包含两个不同时间之间的特定字符串。即如果 foo
存在于以 2016-11-10 06:45:00
和 2016-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
作为 from
和 2016-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 的东西。
我正在搜索一个日志文件,看它是否包含两个不同时间之间的特定字符串。即如果 foo
存在于以 2016-11-10 06:45:00
和 2016-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
作为 from
和 2016-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 的东西。