Apache 로그: sed 또는 awk를 사용하여 매일 몇 개의 서로 다른 IP가 사용됩니까?

Apache 로그: sed 또는 awk를 사용하여 매일 몇 개의 서로 다른 IP가 사용됩니까?

/var/log/apache2/other_vhosts_access.log다음과 같은 파일이 주어지면:

example.com:443 1.1.1.1 - - [25/Jan/2021:12:00:00 +0000] "GET /abc/def/ghi?token=jklm12 HTTP/1.1" 200 1000 "-" "Mozilla/5.0 (Macintosh; Intel...
example.com:443 1.1.1.1 - - [25/Jan/2021:12:10:00 +0000] "GET /abc/def/ghi?token=jklm12 HTTP/1.1" 200 1000 "-" "Mozilla/5.0 (Macintosh; Intel...
example.com:443 2.2.2.2 - - [25/Jan/2021:12:20:00 +0000] "GET /abc/def/ghi?token=jklm13 HTTP/1.1" 200 1000 "-" "Mozilla/5.0 (Macintosh; Intel...
...
example.com:443 33.33.33.33 - - [12/Apr/2021:12:00:00 +0000] "GET /abc/def/ghi?token=jklm14 HTTP/1.1" 200 1000 "-" "Mozilla/5.0 (Macintosh; Intel...
example.com:443 4.4.4.4 - - [13/Apr/2021:12:00:00 +0000] "GET /abc/def/ghi?token=jklm12 HTTP/1.1" 200 1000 "-" "Mozilla/5.0 (Macintosh; Intel...

매일 다른 IP 수를 구하거나 계산하는 방법은 무엇입니까?

예:

 25/Jan/2021
     1.1.1.1
     2.2.2.2
 12/Apr/2021
     33.33.33.33
 13/Apr/2021
     4.4.4.4

또는

 25/Jan/2021  2
 12/Apr/2021  1
 13/Apr/2021  1

"일별 그룹화"를 달성하는 방법은 무엇입니까?

답변1

<infile awk -F'[[ :]' '{
    dt[$7]=(dt[$7]==""?"":dt[$7]) (!seen[$7,$3]++?"\t" $3:ORS) }
END{ for(d in dt)print d ORS dt[d] }'

(dt[$7]==""?"":dt[$7])배열의 이전 내용을 인쇄합니다.dt비어 있지 않은 경우.
(!seen[$7,$3]++?"\t" $3:ORS)인쇄지적 재산권($3) (탭 접두사 포함) 이전에 본 적이 없는 경우DTAE($7), 그렇지 않으면 개행 문자를 인쇄합니다(기본 ORS).

dt[$7]= ...즉, 각 DATE($7)의 내용을 위 결과 값으로 업데이트합니다.


25/Jan/2021
        1.1.1.1
        2.2.2.2
13/Apr/2021
        4.4.4.4
12/Apr/2021
        33.33.33.33

출력 정렬(입력 데이터는 정렬된 순서로 정렬되어야 함)날짜, 로그가 날짜별로 더 자주 정렬될 가능성이 높습니다):

<infile awk -F'[[ :]' '{
    dt[$7]=(dt[$7]==""?"\0"NR"-" $7 ORS:dt[$7]) (!seen[$7,$3]++?"\t" $3:ORS) 
}
END{ for(d in dt) print dt[d] }' |sort -z |cut -z -d'-' -f2-

또는 GNU awk를 사용하여 배열 정렬 옵션을 설정하십시오.

<infile awk -F'[[ :]' '!date[$7]++{ ind++ }
    { dt[ind]=(dt[ind]==""?$7 ORS:dt[ind]) (!seen[$7,$3]++?"\t" $3:ORS)
}
END{ PROCINFO["sorted_in"]="@ind_num_asc"; for(d in dt) print dt[d] }'

25/Jan/2021
        1.1.1.1
        2.2.2.2
12/Apr/2021
        33.33.33.33
13/Apr/2021
        4.4.4.4

답변2

허용되는 답변은 거의 완벽하지만 항상 원치 않는 빈 줄이 있고 때로는 같은 줄에 여러 IP가 있습니다.

그래서 이 작은 수정으로 인해 저에게 효과적이었습니다.

awk -F'[[ :]' '{ dt[$7]=(dt[$7]==""?"":dt[$7]) (!seen[$7,$3]++?"\t"$3"\n":"") } END{ PROCINFO["sorted_in"]="@ind_num_asc"; for(d in dt)print d ORS dt[d] }' other_vhosts_access.log

또는 특정 도메인/페이지의 트래픽을 필터링하려는 경우

grep "example.com" other_vhosts_access.log |awk -F'[[ :]' '{ dt[$7]=(dt[$7]==""?"":dt[$7]) (!seen[$7,$3]++?"\t"$3"\n":"") } END{ PROCINFO["sorted_in"]="@ind_num_asc"; for(d in dt)print d ORS dt[d] }'

관련 정보