こんにちは
突然ですが、Perl で多次元のhash(連想配列)を使う方法です。なぜ急にこんなことを書き出したかというと、いままでいざやろうとすると「あれ?」といつもなるので覚書的に書いておこうかと思いました。
例えばこんなCSVがあったとします。
2020/05/02,10.10.11.1,telnet,net1
2020/05/02,10.10.12.1,telnet,net2
2020/05/02,10.10.11.1,telnet,net1
2020/05/02,10.10.11.1,ftp,net1
2020/05/02,10.10.12.1,telnet,net2
2020/05/02,10.10.11.1,telnet,net1
2020/05/02,10.10.11.1,telnet,net1
これをユニークにするとこんな感じになると思います。
2020/05/02,10.10.11.1,telnet,net1
2020/05/02,10.10.11.1,ftp,net1
2020/05/02,10.10.12.1,telnet,net2
この処理をhash(連想配列)を使ってやってみます。
こんな感じです。hash.pl という名前で保存します。
my %access;
my $line_tmp;
my @access_log;
my $date;
my $ip;
my $port;
my $net;
open (FH_TARGET, "<log.txt") or die "can't open file log.txt";
while ( $line_tmp = <FH_TARGET> ){
@access_log = split(/,/, $line_tmp);
$date = $access_log[0];
$ip = $access_log[1];
$port = $access_log[2];
$net = $access_log[3];
chomp($date);
chomp($ip);
chomp($port);
chomp($net);
$access{$date}{$ip}{$port}{$net} +=1 ;
}
foreach $date ( sort keys %access ){
foreach $ip ( sort keys %{$access{$date}} ) {
foreach $port ( sort keys %{$access{$date}{$ip}} ) {
foreach $net ( sort keys %{$access{$date}{$ip}{$port}} ) {
print "$date,$ip,$port,$net¥n";
}
}
}
}
先程のログを log.txt という名前で保存して、
2020/05/02,10.10.11.1,telnet,net1
2020/05/02,10.10.12.1,telnet,net2
2020/05/02,10.10.11.1,telnet,net1
2020/05/02,10.10.11.1,ftp,net1
2020/05/02,10.10.12.1,telnet,net2
2020/05/02,10.10.11.1,telnet,net1
2020/05/02,10.10.11.1,telnet,net1
perl hash.plとすると、以下の様になりました。
2020/05/02,10.10.11.1,ftp,net1
2020/05/02,10.10.11.1,telnet,net1
2020/05/02,10.10.12.1,telnet,net2
大丈夫そうですね。
すごく巨大なログをやったりするとどうなるのかわかりませんが。。。