2013-06-05 2 views
0

나는 필터 할 항목을 목록에 입력했습니다. 거기에서 그것을 사용하여 필터 :거대한 리눅스 로그 파일을 필터링하십시오.

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 

내가 백 개 메가 로그 파일을 실행 해요 그것은 영원히 취하고있다 ..... 는 파이썬이 일을 할 수있는 더 좋은 방법이 있나요? 목록에서 issuesFound을 변경할 수

+1

왜 당신이 붙박이 리눅스 명령을 사용하지 않는? 뭔가 grep, awk 및 wc 마법을 사용하여 무엇입니까? – Ben

+0

내 일을하면서 우리는 많은 리눅스가이 모든 것을 기록하고있다.문제의 성격에 따라 특정 그룹의 정보를 필터링하고 grep 등으로 좋지 않은 하위 팀으로 필터링 된 로그를 전달할 수 있기를 희망했습니다. – user1678432

+0

부수적으로 이와 같이 명시 적 카운터를 반복하면 코드를 읽기가 더 어려워집니다. 외부 루프를위한'newLogLine for newLogFile :'만이 아니겠습니까? – abarnert

답변

1

봅니다 설정 :

issuesFound = set() 

append 대신 add를 사용

issuesFound.add(line) 
+0

그는'issues' 목록 ('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 이것을 쓸 수 있습니다.)

그리고 그 수단을 in issuesFound: 대신 if line not in issuesFoundCounter:을 검색하면됩니다. 이미 dict이므로 효과적으로 검색 할 수 있습니다. 그러나 setdefault을 사용하거나 dict 대신 defaultdict 또는 Counter을 사용하면 더 간단 해집니다.

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

그리고 당신은 내 빠른 루프와 파이썬에서 느린 틱 명시 적 루프를 제거, 발전기 식으로 그것을 켤 수 있습니다 :

그래서 issuesFoundCounterCounter 경우, 모든 일이에 감소 통역관 배짱. 이것은 단지, 말, 고정 5가 될 것입니다 : 전반에서 선형 - 투 - 일정한 속도 향상에 반대, 1 속도 향상,하지만 고려 여전히 가치 :

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

이 유일한 문제는 issuesFound 목록은 문제가 발견 된 순서가 아니라 임의의 순서로 표시됩니다. 중요하다면 Counter 대신 OrderedCounter을 사용하면됩니다. 거기 collections 문서에 간단한 조리법은, 그러나 귀하의 경우에, 그것은 간단 할 수 있습니다

class OrderedCounter(Counter, OrderedDict): 
    pass 
+0

그냥 이것으로 완전히 해결한다고 말하고 싶습니다. – user1678432

+0

주석과 서명 사이의 빈 공간으로 완전히 해결할 수있는 문제는 좋은 문제입니다. :) – abarnert

관련 문제