2016-11-10 55 views
0

我在搜索日志文件以查看它是否包含两个不同时间之间的某个字符串。即如果在以2016-11-10 06:45:002016-11-10 10:45:00的时间戳开始的行之间存在foo,则threshold变量设置之间的时间,例如240将是4小时。使用Awk和Grep查找日志文件中两次之间的行

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 '$0 >= "$from" && $0 <= "$current"' /path/file.log | grep "foo" 
then 
    exit 0 
else 
    exit 1 
fi 

但是我不知道为什么,但是当我在if声明传递命令行$from$current,它实际上没有阅读它。这是因为如果我路过垃圾所以它不是比较日期权,将返回所有的行并退出0

但如果我手动放在日期在if声明,即2016-11-10 06:45:00from2016-11-10 10:45:00current然后它返回这两个日期之间的正确行,然后我可以使用grep来检查这些行是否包含foo

我真的不明白为什么我的代码不能正常工作,而且由于我需要通过更改threshold变量来根据需要在两个不同时间之间检查日期,因此无法手动输入日期。

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

感谢。

+0

这可能有助于:[Schwartzian变换](https://en.wikipedia.org/wiki/Schwartzian_transform) – Cyrus

+0

你不需要'if ...;然后退出0;其他出口1; fi'构造:如果你不这么做,你的脚本将以grep的退出状态退出。 –

回答

3

您试图让bash展开变量单引号......运行s="string"; echo '$s',您会看到我的意思。

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

“但这就是awk的参数”...... awk知道如何处理$ 0和$ 1,所以awk正在适当地扩展它们。但你期待awk得到'$0 >= "some_time" && $0 <= "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" '$0 >= f && $0 <= c' /path/file.log | grep "foo"

退房http://www.catonmat.net/blog/ten-awk-tips-tricks-and-pitfalls/这篇文章实际上有一些很好的洞察巧妙的事情,你可以使用awk做。你可能能够在这里使用“分割文件模式”来减少你使用的命令的数量,但无论哪种方式你都会学到一些关于awk的知识。

+1

变量“to”和“from”包含空格,所以引用是至关​​重要的:'awk -v from =“$ from”-v c =“$ current”...' –

+0

修正答案以反映@glenn –