2013-06-05 82 views
0

我有用戶輸入到列表中的項目,它想過濾掉。從那裏,它過濾使用:過濾大量的linux日誌文件

while knownIssuesCounter != len(newLogFile): 
    for line in knownIssues: 
     if line in newLogFile[knownIssuesCounter]: 
      if line not in issuesFound: 
       issuesFoundCounter[line]=1 
       issuesFound.append(line) 
       issuesFound.append(knownIssues[line]) 
      else: 
       issuesFoundCounter[line]=issuesFoundCounter[line] + 1 
    knownIssuesCounter +=1 

我運行到幾百梅格日誌文件,並且它永遠走..... 有沒有更好的辦法是使用Python這樣做呢?

+1

你爲什麼不使用內置的Linux命令?一些有點grep,awk和wc魔術? – Ben

+0

隨着我的工作,我們在許多Linux日誌上工作,所有這些性質。希望能夠根據問題的性質過濾出某些信息組,然後將過濾的日誌傳遞給grep等不太好的較低的團隊。 – user1678432

+0

作爲一個方面說明,像這樣的顯式計數器迭代會使代碼難以閱讀。爲什麼不爲'newLogFile中的newLogLine:'爲外部循環? – abarnert

回答

1

嘗試從列表中更改issuesFound設置:

issuesFound = set() 

,並使用add代替append

issuesFound.add(line) 
+0

我想他想要'issuesFound'列表(它包含'line'和'knownIssues [line]',並且順序可能很重要),但是他也希望一個'set'做快速檢查,如果已經看過」。 – abarnert

0

的代碼是如此緩慢的一個重要原因,就是if line not in issuesFound:。這需要通過一個巨大的列表進行線性搜索。

您可以通過添加set看到的問題(這是有效的免費搜索)來解決該問題。這會將您的時間從O(NM)減少到O(N)。

但實際上,您可以通過完全刪除if來簡化操作。

首先,您可以根據issuesFoundCounter的鍵值生成issuesFound列表。對於issuesFoundCounter中的每一行,您需要該行,然後是其knownIssues[line]。所以:

issuesFound = list(flatten((line, knownIssues[line]) for line in issuesFoundCounter)) 

(我使用從itertools文檔的flatten配方您可以複製到你的代碼,或者你可以寫這與itertools.chain.from_iterable代替flatten。)

,這意味着你可以搜索if line not in issuesFoundCounter:而不是in issuesFound:,這已經是dict(因此可以有效地免費搜索)。但是,如果您只使用setdefault - 或者更簡單,則可以使用defaultdictCounter而不是dict - 您可以自動進行此操作。

所以,如果issuesFoundCounterCounter,整個事情簡化爲這樣:

for newLogLine in newLogFile: 
    for line in knownIssues: 
     if line in newLogLine: 
      issuesFoundCounter[line] += 1 

而且你可以把它轉換成一臺發電機的表達,從而消除在Python緩慢上下的明確循環裏面的快循環口譯員的膽量。這只是將是,比如說,一個固定的5:1的加速,而不是從上半年的線性 - 不斷加速,但它仍然是值得考慮的:

issuesFoundCounter = collections.Counter(line 
             for newLogLine in newLogFile 
             for line in knownIssues 
             if line in newLogLine) 

與此唯一的問題是issuesFound列表現在按照任意順序排列,而不是按照發現問題的順序排列。如果這很重要,只需使用OrderedCounter而不是Counter。有一個簡單的配方在collections文檔,但是對於你的情況,因爲它可以作爲簡單:

class OrderedCounter(Counter, OrderedDict): 
    pass 
+0

只想說我完全用這個解決了這個問題: – user1678432

+0

任何問題都可以通過評論和簽名之間的空白空間完全解決,這是一個很好的問題。 :) – abarnert