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] }'

関連情報