2012-08-25 2 views
1

로그 파일에 줄이 포함되어 있는데, 각 묶음은 빈 줄로 구분됩니다. 나는 한 줄의 줄마다 특정 줄 (공통 패턴 포함)을 grep하고 싶다. 각 줄은 메일에 관한 것입니다.awk를 사용하여 여러 행의 각 묶음에서 grep을 수행합니다.

#START# 
03:48:19:798: : <23/08/2012 03:48:19:019> 
03:48:19:798: : <---23/08/2012 03:48 ---> 
03:48:19:799: : MAIL FROM IP=1.2.3.4 
03:48:19:799: : START CHECKING OF IPLIMIT 
03:48:19:799: : STOP CHECKING OF IPLIMIT 
03:48:20:848:In : MAIL FROM: <[email protected]> 
03:48:20:848: : [A:A:A] 
03:48:20:849: : max attach size-->5242880 
03:48:20:856: : User Is Authenticated with "[email protected] and domain abc.com" 
03:48:20:856: : Passed 
03:48:20:987:In : RCPT TO: <[email protected]> 
03:48:20:987: : email [email protected] 
03:48:20:992: : [A:A:A] 
03:48:20:999: : passed 
03:48:20:999:Inside the Store Mails 
03:48:20:999: : BCC feature is not applicable [email protected] 
03:48:21:000: : BCC feature is not applicable from [email protected] 
03:48:21:000:Inside the Store 
03:48:21:132:In : RCPT TO: <[email protected]> 
03:48:21:132: : email [email protected] 
03:48:21:133: : [A:A:A] 
03:48:21:140: : passed 
03:48:21:140:Inside the Store Mails 
03:48:21:140: : BCC feature is not applicable [email protected] 
03:48:21:140: : not authenticated 
03:48:21:140:Inside the Store 
03:48:21:271: : Data Received 
03:50:32:049: : 552 Size Limit Exceeded(5242880) 
03:50:32:049: : File Moved in LargeSize Folder.... 
03:50:32:049: : File Moved in LargeSize Folder.... 
03:50:32:049: : Connection closed 
03:50:32:049: : File Deleted /home/Mail//mailbox/LargeSize/[email protected]:24085.444724474357(1345673901000) 
03:50:32:051: : File Deleted /home/Mail//mailbox/LargeSize/[email protected]:39872.512978520455(1345673901140) 
MAIL DATA : : 6815779 Bytes 
Total: Conn : 16713 Quit By Host : 5565 Stored : 11134 Loop:0 
#END# 
W A R N I N G ---------------W A R N I N G 

...Waiting for activity on port Total Thread Started & 16732 Stoped 16730 
#START# 
03:56:20:790: : <23/08/2012 03:56:20:020> 
03:56:20:790: : <---23/08/2012 03:56 ---> 
03:56:20:791: : MAIL FROM IP=2.3.4.5 
03:56:20:792: : IP IS FRIEND IN WHITELIST 
03:56:20:834:In : MAIL FROM:<[email protected]> 
03:56:20:834: : [A:A:A] 
03:56:20:834: : null 
03:56:20:834: : Passed 
03:56:20:834:In : RCPT TO: <[email protected]> 
03:56:20:834: : email [email protected] 
03:56:20:835: : Mailing List 
03:56:20:835: : [A:A:A] 
03:56:20:836: : passed 
03:56:20:836: : Proceesing maillist 
03:56:20:839: : Data Received 
03:56:20:865: : /home/Mail//mailbox/MailingList/[email protected]:79602.39544573233(1345674380836) Msg Queued For Delivery 
03:56:20:865: : Msg forward successfully 
03:56:20:865: : /home/Mail//mailbox/MailingList/M14310.39892966699(1345674380837) Msg Queued For Delivery 
MAIL DATA : : 27985 Bytes 
Total: Conn : 16732 Quit By Host : 5582 Stored : 11135 Loop:0 
#END# 

...Waiting for activity on port Total Thread Started & 16735 Stoped 16731 
#START# 
03:56:23:957: : <23/08/2012 03:56:23:023> 
03:56:23:957: : <---23/08/2012 03:56 ---> 
03:56:23:958: : MAIL FROM IP=2.3.4.5 
03:56:23:959: : IP IS FRIEND IN WHITELIST 
03:56:23:999:In : MAIL FROM: <[email protected]> 
03:56:23:999: : [A:A:A] 
03:56:23:999: : null 
03:56:23:999: : Passed 
03:56:23:999:In : RCPT TO: <[email protected]> 
03:56:23:999: : email [email protected] 
03:56:24:000: : [A:A:A] 
03:56:24:007: : passed 
03:56:24:008:Inside the Store Mails 
03:56:24:009: : BCC feature is not applicable [email protected] 
03:56:24:009: : not authenticated 
03:56:24:009:Inside the Store 
03:56:24:009: : Data Received 
03:56:24:053: : /home/Mail//mailbox/External/[email protected]:50098.70335800691(1345674384009) Msg Queued For Delivery 
03:56:24:054: : Msg forward successfully 
MAIL DATA : : 28276 Bytes 
Total: Conn : 16735 Quit By Host : 5582 Stored : 11136 Loop:0 
#END#  

여기 [email protected], 그리고 [email protected], [email protected] 외부 메일 번호이다 내부 메일 식별자이며, 다음과 같이 샘플 로그 파일이다. 각 메일에 대해 # START #부터 # END #까지의 줄이 생성됩니다.

각 줄마다 패턴 일치를 실행하고 싶습니다. 메일이 내부 전자 메일 ID에서 외부 전자 메일 ID (줄의 두 번째 묶음)에 이르는 여러 줄의 줄만 필요합니다.

메일이 외부 전자 메일 주소/ID에서 내부 전자 메일 ID (첫 번째 묶음)로 또는 내부 전자 메일 ID에서 내부 전자 메일 ID로 바뀌는 것을 원하지 않습니다. (셋째 줄).

메일이 내부에서 외부로가는 줄이 많으면 단어 FROMTO이 포함 된 줄을 추출하고 싶습니다.

나는에서 시작하여 한 줄의 기록을 만들기 위해 #START#에서 끝나는 라인의 각 무리를 변환하는 AWK의 RS, ORS, FSOFS 변수를 사용했지만, 수 없습니다. 뉴 라인을 | 또는 ~과 같은 구분 기호로 바꿀 수는 없습니다. 또한 각 리소스 레코드에서 여러 패턴 일치를 실행하는 방법을 지금은 설명하지 않습니다.

/PATTERN/ 옵션을 사용해 보았지만 system() 함수를 사용하여 grep 명령을 실행하지 못하여 도메인 이름을 확인할 수 없습니다. 그것은 나를 오류를 줬다 : sh: 1: not found. 그것을 깨뜨릴 수 없었습니다. 나는 코드의 다음과 같은 유형을 사용하여 각 레코드를 내보내려고하면, 그 작동하지 않는, 또한

if ($0 ~ /FROM/) { print $0 | system("egrep -i 'FROM|TO'") } 

:

for i in $(cat log_file | awk_file_givin_1_resource_record_at_a_time) ; do pattern_matching_commands ; done 

그것의 더 작업은 패턴 매칭 라인에 노력하고 있습니다 일으키지 나는 코드를 사용 한 번에 한꺼번에 작업하고 싶습니다.

+0

이것은 다소 광범위하다고 느낍니다. 여기에는 많은 개인적인 질문이 있습니다. 문제를 단계별로 나누고 각 단계를 개별적으로 해결하려고합니다. 특정 단계에 문제가있는 경우 여기에서 질문하는 것이 더 좋고 집중된 질문이됩니다. – chepner

+0

@chepner : 나는 변수의 각 묶음을 가져 와서 그 변수를 bash 명령과 함께 사용하면, 내가 원하는 정보를 추출하기 위해 보통의 bash 연산을 수행 할 수있다. –

답변

2

나는 다음과 같은 BASH 스크립트가 잘 작동 생각하지만, 당신은 당신의 로그의 크기에 대한 벤치 마크를 수행해야합니다

#!/bin/bash 

INTERNAL_DOMAINS="${1:-xyz.com|xyz.net}" 

declare -i LINES BYTES VALIDS 
LINES=0 
BYTES=0 
VALIDS=0 
STATUS=stopped 
while read LINE 
do 
    if [ "$STATUS" = stopped ] 
    then 
    if [ "${LINE:0:7}" = "#START#" ] 
    then   
     STATUS=started  
     PARA=""   
    fi   
    else 
    if [ "${LINE:0:5}" = "#END#" ] 
    then   
     if [ $STATUS = valid ] 
     then    
     VALIDS+=1    
     echo "$PARA" | egrep -w "FROM|TO" 
     echo -e "$VALIDS matched\t----------------------------------------" 
     fi     
     STATUS=stopped  
    elif (echo "$LINE" | fgrep -q "RCPT TO") && (echo "$LINE" | egrep -qiv "@($INTERNAL_DOMAINS)") 
    then   
     STATUS=valid  
     PARA+="$LINE  
" 
    else   
     PARA+="$LINE  
" 
    fi   
    fi 

    LINES+=1 
    BYTES+=${#LINE} 
    BYTES+=1 
    echo -en "\rRead: lines: $LINES | kB: $(($BYTES/1024)) | matches: $VALIDS " >&2 
done 

당신은 실행으로 위의 스크립트를 설정하고이처럼 실행해야합니다 진행 상황 출력 :

time ./filter.sh "one.int.com|two.int.com" <sample.log> report.out 
+0

이것은 나를 위해 일했습니다. 고마워. 나는 프로그래머 또는 스크립터로서 갈 길이 멀다는 것을 인정해야한다 ..... –

2

레코드 사이에 항상 빈 줄이 있고 레코드 내에서 빈 줄이없는 경우 awk의 "단락 모드"를 사용하십시오. RS을 빈 문자열로 설정하십시오. 당신이 정말로 #START##END# 마커를 사용해야하는 경우 당신이 함께 가기로

awk -v RS= ' 
    /^[0-9:]*In : MAIL FROM: <[^<>]*@example\.com>$/ && 
    /^[0-9:]*In : RCPT TO: <[^<>]*@example\.com>$/ { … } 
' 

는 변수에 데이터를 축적. #END#에 도달하면 처리를 수행하고 변수를 재설정합니다. 필요한 경우 다음 #START#까지 처리를 비활성화하십시오.

BEGIN { in_record = 1; } 
/^#START#$/ { in_record = 1; } 
!in_record { next; } 
/^[0-9:]*In : MAIL FROM: <([^<>]*)>$/ { from = $0; sub(/.*</, "", from); sub(/>.*/, "", from); } 
… 
/^#END#$/ { 
    /* processing goes here */ 
    from = ""; 
    in_record = 0; 
} 
+0

답장을 보내 주셔서 감사합니다 :).하지만 첫 번째 해결 방법을 사용하는 방법을 알 수 없습니다. 두 번째 것은 매우 복잡해 보인다. 내 로그 파일 이름이 log_20120824.log 인 경우 사용법은 무엇입니까? 나는 첫 번째 해결책으로 파일의 파이핑 cat 출력을 시도하여 도메인 이름을 대체했지만 아무 일도 일어나지 않았습니다. 또한 "print $ 0"을 사용하여 아무 것도 인쇄했습니다. –

관련 문제