2016-11-10 44 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 –

相關問題