有一个日志文件,其中每行包含由空格分隔的字段.其中一个字段是源节点的IP地址.我们想要找到具有最多日志条目的IP地址列表.让我们说找到大多数日志条目的前10个IP地址.
这是Perl访谈问题.面试官想知道候选人将如何进行.
PS:这个问题是我的朋友问的
我的回复,先生或采访女士,将基于几个问题的答案.第一组问题如下.当然,这些答案可能会产生其他问题.
你说"其中一个领域".我们知道哪个领域?它总是相同还是变化?
日志只有IPv4,只有IPv6,还是两者兼而有之?IPv4和IPv6之间的地址映射是否需要计算,或者映射是否可以作为唯一的源节点处理?
日志文件有多大?有多少内存可以解决问题?
CPAN模块是否可供使用,或者解决方案仅限于核心模块或其他"已批准"模块列表?
假设IP地址出现在N列中:
use strict;
use warnings;
use constant N => 3;
my %counts;
while (<>)
{
my(@fields) = split /\s+/;
$counts{$fields[N]}++;
}
Run Code Online (Sandbox Code Playgroud)
这给了你一个I/P地址的哈希和相应的计数.
my %iplist;
foreach my $address (keys %counts)
{
my $count = $counts{$address};
push @{$iplist{$count}}, $address;
}
Run Code Online (Sandbox Code Playgroud)
这会给你一个计数哈希,并与每个计数相关联,这个计数的IP地址列表.
use constant Wanted => 10;
my $printed = 0;
foreach my $count (sort { $b <=> $a } keys %iplist)
{
print "$count: @{$iplist{$count}}\n";
$printed += scalar(@{$iplist{$count}});
last if $printed >= Wanted;
}
Run Code Online (Sandbox Code Playgroud)
将计数排序为反向(降序)顺序,并打印出多次出现的计数和IP地址列表.它还计算打印的地址数,并在满足或超过所需数量时停止循环.