2015-01-19 6 views
2

로그 파일에 1 백만 라인이 넘는 로그 파일이 있습니다. 특정 사용자 이름을 기반으로 로그에서 일부 데이터를 추출하려고합니다.RegExp로 Redmine 로그 파일에서 데이터를 추출합니다.

로그 샘플 :

Started POST "/projects/some-project/issues/update_form.js" for 194.176.105.12 at Tue Jun 10 14:58:59 +0200 2014 
Processing by IssuesController#update_form as JS 
    Parameters: {"issue"=>{"is_private"=>"0", "done_ratio"=>"0", "fixed_version_id"=>"", "tracker_id"=>"2", "assigned_to_id"=>"", "due_date"=>"", "custom_field_values"=>{"12"=>[""], "16"=>[""]}, "subject"=>"", "start_date"=>"", "estimated_hours"=>"", "description"=>"", "status_id"=>"1", "priority_id"=>"2"}, "project_id"=>"barnet-and-chase-farm", "attachments"=>{"screenshot"=>{"name"=>"screenshot", "content"=>"", "description"=>""}}, "utf8"=>"✓", "authenticity_token"=>"sometoken"} 
    Current user: SOME.USERNAME (id=20) 
    Rendered issues/_form_custom_fields.html.erb (3.7ms) 
    Rendered issues/_attributes.html.erb (397.9ms) 
    Rendered plugins/redmine_screenshot_paste/app/views/issues/_screenshot.html.erb (0.6ms) 
    Rendered issues/_form.html.erb (418.6ms) 
    Rendered issues/update_form.js.erb (422.3ms) 
Completed 200 OK in 1032.4ms (Views: 406.6ms | ActiveRecord: 22.7ms) 

로그 파일이 위의 많은 반복 블록을 가지고있다. 블록의 내용은 가변적입니다. 즉, 다른 데이터, 줄 수 등이있을 수 있습니다. 그러나 모든 블록은 Started 문자열로 시작하고 Completed 문자열로 끝납니다. 두 줄은 항상 새 줄의 1 열에 있습니다.

나는 문자열 Current user: SOME.USERNAME

이를 달성하는 가장 좋은 방법은 무엇입니까를 포함하는 블록 만 추출 할 필요가? RegExp이 트릭을 수행 할 것으로 추측하고 있지만 원하는 결과를 얻기 위해 어떻게 작성해야할지 모르겠습니다.

Linux 명령 줄 (grep 등) 또는 Sublime Text 나 ​​Notepad ++와 같은 소프트웨어 또는 커뮤니티에서 권장하는 Python 스크립트와 같은 소프트웨어를 사용할 수 있습니다. 당신이 정규식 사용할 수 있습니다

+0

로 부를 수있는 스 니펫 레드 마인인가 당신이하고있는 것에 부적합한 API가 있습니까? (불쾌감을 묻지 않고, 당신이 그것에 대해 알고 있는지 궁금해하고 있습니다.) http://www.redmine.org/projects/redmine/wiki/Rest_api –

답변

2

: 조금 파이썬으로

(?ms)^Started [^\n]*(?:(?!^Completed\b).)*?Current user: SOME\.USERNAME\b.*?^Completed\b[^\n]* 

당신이

import sys, re 

user= sys.argv[2] 
pattern= r'(?ms)^Started [^\n]*(?:(?!^Completed\b).)*?Current user: %s\b.*?^Completed\b[^\n]*'%re.escape(user) 
with open(sys.argv[1]) as f: 
    print '\n'.join(re.findall(pattern, f.read())) 

처럼 뭔가를하고

python my_script.py /path/to/log_file.txt SOME.USERNAME 
+0

이 멋진 솔루션에 감사드립니다. 작동하는 것처럼 보이지만 결과를 한 줄로 출력합니다. 출력을 만들 때 원래 줄 바꿈을 유지하려면 어떻게해야합니까? 나는 파이썬 스크립트를 사용하여 이것을 실행하고있다 :'python my_script.py /path/to/log_file.txt SOME.USERNAME> output.log' ...'import sys, re' 라인에 추가하고 싶을 수도있다. 답변을 완성하기 위해 스크립트 상단으로 나는 그것을 올바른 것으로 표시 할 것이다! :) – Adam

+1

@Adam : SO는 코드 작성 서비스가 아닙니다. 한숨. 답변이 업데이트되었습니다. –

+0

당신은 절대적으로 옳습니다. 죄송합니다. 나는 그것을 직접 디버깅해야했다. 나는 또한 당신의 대답을 직접 편집 할 수 있다는 것을 깨닫지 못했습니다. 도움을 주셔서 감사합니다 (그것은 완벽하게 작동합니다) 그리고 나는 당신의 코멘트에서 교훈을 배울 것입니다 - 미안 해요! – Adam

관련 문제