2012-04-06 3 views
0

큰 로그 파일 행에서 일부 정보를 구문 분석해야합니다. awk를 사용하여 로그 라인 구문 분석

abc.log:2012-03-03 11:12:12,457 ABC[123.RPH.-101] XYZ: Query=get_data @a=0,@b=1 Rows=10Time=100 

위의 로그 파일에 같은 많은 로그 라인이 있습니다

같은 그 뭔가. 나는 같은 정보를 추출 할 필요가 날짜 예 : 2012-03-03 11 : 12 : 12,457 작업의 세부 사항 즉 123.RPH.-101 쿼리 즉 get_data (매개 변수없이) 행 그래서 10 시간 즉 100

을 즉 내가 AWK 다양한 순열 계산을 시도했지만 점점 오른쪽하지 않은

2012-03-03 11:12:12,457|123|-101|get_data|10|100 

처럼 출력이 보일 것입니다.

@(collect :vars()) 
@file:@[email protected]@day @hh:@mm:@ss,@ms @jobname[@[email protected]] @queryname: [email protected] @params [email protected]{rows /[0-9]+/}[email protected] 
@(output) 
@[email protected]@day @[email protected]@ss,@ms|@job1|@job2|@query|@rows|@time 
@(end) 
@(end) 

실행 :

+0

'Rows = 10Time = 100'은 원래'Rows = 10 Time = 100'이 되길 바랍니다. – C2H5OH

+0

은 로그 파일에서 "abc.log :"입니까, 아니면 그 grep 출력입니까? –

답변

1

음,이 ...

sed -e 's/[^0-9]*//' -re 's/[^ ]*\[([^.]*)\.[^.]*\.([^]]*)\]/| \1 | \2/' -e 's/[^ ]* Query=/| /' -e 's/ [^ ]* Rows=/ | /' -e 's/Time=/ | /' my_logfile 
1

TXR 정말 무서운이지만, sed 때문에 태그에 아무 대답은 아직 없다

$ txr data.txr data.log 
2012-03-03 11-12-12,457|123|-101|get_data|10|100 

로그 파일의 모든 줄이 패턴과 일치해야한다는 것을 프로그램에 알리는 한 가지 방법이 있습니다. 첫째, 컬렉션에 틈새를 허용하지 마십시오. 이 말에 일치하는 항목을 지정

@(eof) 

: 우리가 이것을 추가 스크립트의 끝에서,

@(collect :gap 0 :vars()) 

둘째 :이 일치하지 않는 물질이 바로 일치하는 라인을 찾기 위해 생략 할 수 없음을 의미 파일의. 일치하지 않는 행 (:gap 0 제약 조건)으로 인해 @(collect)이 빠르면 @(eof)이 실패하므로 스크립트가 실패한 상태로 종료됩니다.

이 유형의 작업에서는 필드 분할 정규식 해킹이 처리되는 입력의 일부 하위 집합에 대해 맹목적으로 잘못된 결과를 생성 할 수 있기 때문에 역화됩니다. 입력에 막대한 수의 행이 포함되어 있으면 실수를 쉽게 확인할 수있는 방법이 없습니다. 패턴을 기반으로하는 예제와 닮지 않은 것을 거부 할 가능성이있는 매우 구체적인 일치를 갖는 것이 가장 좋습니다.

+0

이 도구/언어는 정말 재미있어 보입니다. 게시 해 주셔서 감사합니다. –

+0

'Rows = 10Time = 100'은 질문에 지정된대로 처리됩니다. 그것은 우리가 정규 표현식에 도달하기 위해 정당화되는 상황의 훌륭한 예입니다. – Kaz

1

내 해결책 gawk : gawk 확장을 사용하여 일치시킵니다.

파일 형식을 지정하지 않았으므로 정규 표현식을 조정해야 할 수 있습니다.

스크립트 호출 : 여기 gawk -v OFS='|' -f script.awk

{ 
match($0, /[0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+,[0-9]+/) 
date_time = substr($0, RSTART, RLENGTH) 

match($0, /\[([0-9]+).RPH.(-?[0-9]+)\]/, matches) 
job_detail_1 = matches[1] 
job_detail_2 = matches[2] 

match($0, /Query=(\w+)/, matches) 
query = matches[1] 

match($0, /Rows=([0-9]+)/, matches) 
rows = matches[1] 

match($0, /Time=([0-9]+)/, matches) 
time = matches[1] 

print date_time, job_detail_1, job_detail_2, query,rows, time 
} 
1

다른, 덜 공상, AWK 솔루션입니다 (하지만 너무 mawk의 작동) :

BEGIN { OFS="|" } 

{ 
    i = match($3, /\[[^]]+\]/) 
    job = substr($3, i + 1, RLENGTH - 2) 
    split($5, X, "=") 
    query = X[2] 
    split($7, X, "=") 
    rows = X[2] 
    split($8, X, "=") 
    time= X[2] 

    print $1 " " $2, job, query, rows, time 
} 

Nothe을이이 Rows=10Time=100 문자열이 분리되어 가정합니다 즉, 질문의 예에서 오타가 있었던 것입니다.

0

그냥 오른쪽 필드의 구분이

awk -F '[][ =.]' -v OFS='|' '{print $1 " " $2, $4, $6, $10, $15, $17}' 

나는 믿고있어 필요 "abc.log를"로그 파일에 실제로 아니다.