有一个日志文件,其中每行包含以空格分隔的字段。其中一个字段是源节点的IP地址。我们想要找到具有最多日志条目的IP地址列表。让我们说找到大多数日志条目的前10个IP地址。
这是Perl采访问题。面试官想知道候选人将如何进行。
P.S:问我的朋友
答案 0 :(得分:7)
我的回复,先生或采访女士,将基于几个问题的答案。第一组问题如下。当然,这些答案可能会产生其他问题。
你说“其中一个字段。”我们知道哪个领域?它总是相同还是变化?
日志只有IPv4,只有IPv6,还是两者兼而有之? IPv4和IPv6之间的地址映射是计数中的一个问题,还是可以将映射视为唯一的源节点?
日志文件有多大?有多少内存可以解决问题?
CPAN模块是否可供使用,或者解决方案仅限于核心模块或其他“已批准”模块列表?
答案 1 :(得分:6)
假设IP地址出现在N列中:
use strict;
use warnings;
use constant N => 3;
my %counts;
while (<>)
{
my(@fields) = split /\s+/;
$counts{$fields[N]}++;
}
这给你一个I / P地址和相应计数的哈希值。
my %iplist;
foreach my $address (keys %counts)
{
my $count = $counts{$address};
push @{$iplist{$count}}, $address;
}
这会给你一个计数哈希值,并与每个计数相关联,列出具有该数量的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;
}
将计数排序为反向(降序)顺序,并打印出多次出现的计数和IP地址列表。它还会计算打印的地址数量,并在达到或超过所需数量时停止循环。
答案 2 :(得分:0)
询问这是否适合一次性使用。
如果不是,Jonathan的回答很好。
如果是,请使用单行。
假设第一个字段包含IP:
perl -ane '$count{$F[0]}++ } END { print $_, "\n" for (sort { $b <=> $a } keys %count)[0..9]'
一个很好的问题,测试候选人对数据结构,字符串数组操作,排序和数组切片使用的了解。