2016-01-31 74 views
0

我有一個接近3GB的巨大日誌文件。在Linux中優化搜索

我的任務是根據記錄日誌的次數生成一些報告。

我需要找到時間的數量StringA,StringB,StringC被單獨調用。

我在做什麼現在的問題是:

grep "StringA" server.log | wc -l 
grep "StringB" server.log | wc -l 
grep "StringC" server.log | wc -l 

這是一個漫長的過程,我的腳本需要近10分鐘才能完成。我想知道的是,這是否可以優化?是可以運行一個grep命令並找出時間的數量StringA,StringB和StringC已被單獨調用?

+2

您可以使用'grep -c'而不是'wc -l':'grep -c「StringA」server.log'。 'grep'不能報告單個字符串的數量。您可以使用'awk':'awk'/ StringA/{a ++;}/StringB/{b ++;}/StringC/{C++;} END {print a,b,c}'server.log'。 –

+0

@ l3x我正準備寫一個答案,裏面包含了你在這個評論中寫下的內容,然後我看到了這個評論......關心把它變成答案? –

+0

@BenjaminW。由於OP正在尋找「快速」解決方案,所以我不願意發佈它。我不確定這對他是否足夠快。無論如何發佈。 –

回答

1

當然,這種方法可以優化,因爲grep不執行任何文本索引。我會使用文本索引引擎,如this reviewstackexchange QA。你也可以考慮使用systemd中的journald,它以結構化和索引格式存儲日誌,所以查找更有效。

1

所以很多greps這麼短的時間... :-)

根據David Lyness,直grep搜索約爲7倍的速度在大文件搜索的awk

如果是這樣的話,目前的辦法,可以通過改變grepfgrep優化,但前提是被搜索模式的是正則表達式。 fgrep針對固定模式進行了優化。

如果實例的數量相對較少,相比原來的日誌文件中的條目,也可能是使用egrep版本的grep創建擺滿了三個實例的臨時文件的改進:

egrep "StringA|StringB|StringC" server.log > tmp.log 
grep "StringA" tmp.log | wc -c 
grep "StringB" tmp.log | wc -c 
grep "StringC" tmp.log | wc -c 

grepegrep變體允許在兩個或多個單獨的搜索字符串之間使用|(豎線/豎線)字符,以便您可以在語句中查找多個字符串。您可以使用grep -E來做同樣的事情。

完整的文檔是在man grep網頁和有關egrep命令從man 7 re_format命令使用的擴展正則表達式的信息。

+0

儘管如此,這些並不單獨顯示OP的要求。 –

+1

感謝您的觀察,我確實忽略了對單獨計數的需求。我已經修改了我的答案來補救。 –

+0

David Lyness測試中的'awk'不僅僅是簡單地計算正則表達式匹配。 'grep'可能會快一點,但我懷疑它比同等的awk快7倍。 – chepner

3

可以使用grep -c代替wc -l

grep -c "StringA" server.log 

grep不能報告個人弦數。您可以使用AWK:

out=$(awk '/StringA/{a++;} /StringB/{b++;} /StringC/{c++;} END{print a, b, c}' server.log) 

然後你就可以提取每一個簡單的數組數:

arr=($out) 
echo "StringA="${arr[0]} 
echo "StringA="${arr[1]} 
echo "StringA="${arr[2]} 

這(grepwc)肯定會更快,可能awk解決方案也越來越快。但我沒有測量任何。

+0

我希望awk要快得多,因爲它只讀過一次文件,三次greps必須經過三次。 –