【问题标题】:print each ip address with number of GET /PUT /POST /DELETe request in perl在 perl 中使用 GET /PUT /POST /DELETe 请求的数量打印每个 IP 地址
【发布时间】:2018-01-19 11:48:31
【问题描述】:

我有一个 apache 日志,如下所示。

192.168.10.20 - - [18/Jul/2017:08:41:37 +0000] "PUT /search/tag/list HTTP/1.0"

10.30.24.3 - - [18/Jul/2017:08:45:15 +0000] "POST /search/tag/list HTTP/1.0"

192.168.10.20 - - [18/Jul/2017:09:04:09 +0000] "GET /apps/cart.jsp?appID=4651 HTTP/1.0"

192.168.10.20 - - [18/Jul/2017:09:04:09 +0000] "GET /apps/cart.jsp?appID=4651 HTTP/1.0"

10.30.24.3 - - [18/Jul/2017:08:45:15 +0000] "POST /search/tag/list HTTP/1.0"


它由具有不同请求类型的多次相同IP地址组成。 任何人都可以在 perl 中给出一个解决方案来提取所有的 IP 地址,对它们进行分组,并且没有每个 IP 地址的 POST/GET/DELETE 请求。 输出格式应该是

192.168.10.20:GET=23,POST=13,PUT=23,DELETE=11

43.56.76.4:GET=4,POST=3,PUT=1,DELETE=3

到目前为止,我已经完成了这项工作,提取了 ip 和请求类型并登录到另一个文件,然后计算了每次出现的次数:

my $file = "apache_log.log";
my $file2 = "apache_log1.log";
my %hrec;
open (FH, "$file");
open(DATA, ">$file2");
my $str;
while (my $line = <FH>) {
chomp $line;
if  ( $line =~ /^(\d{1,}\.\d{1,}\.\d{1,}\.\d{1,})\s+\-\s+\-\s+\[\d{1,}\/\w+\/\d{1,}\:\d{1,}\:\d{1,}\:\d{1,}\s+\+0000\]\s+\"(PUT|GET|POST|DELETE)/)   {
print DATA "$1: $2\n";
}
close(DATA);
close(FH);
open(DATA, "$file2") or die "Couldn't open file $file2, $!";
while ( my $str = <DATA>) {
my @requests = split ('\n',$str);
foreach my $req(@requests) {
$hrec{$req}++;
 }
 }
close(DATA);
foreach my $fam ( sort keys %hrec) {
print "$fam =". ($hrec{$fam})."\n";
}

-- 但我的输出如下 192.168.10.20:GET=23

192.168.10.20:POST=16

43.56.76.4:GET=4

43.56.76.4:POST=3

等等。``

【问题讨论】:

  • 我投票决定将此问题作为题外话结束,因为 stackoverflow 不是代码编写服务。 OP 只是提供了问题,并没有尝试自己解决。
  • 正则表达式::Log::Common
  • @SteffenUllrich ..对不起..我已经尝试过,现在粘贴了我的程序。如果您能提供帮助,将会很有帮助。
  • @SaketKumar:我建议您查看格式错误的帖子,并了解如何正确格式化。有一些方法可以正确格式化代码等。如果您希望其他人投入空闲时间来帮助您,请让其他人阅读您的帖子。
  • 使用两级哈希作为数据结构。然后迭代您的日志文件,从每一行中选择 IP 和方法并执行$num_requests{$ip}{$method} += 1;

标签: regex perl ip-address


【解决方案1】:
open(FileHandle, "<$ARGV[0]");
%hash = ();
while(<FileHandle>)
{
    chomp($_);
    if($_ =~ /^(\d{1,}\.\d{1,}\.\d{1,}.\d{1,})/) { $ip = $1; }
    if($_ =~ /GET/) { $hash{$ip}{"GET"}++; }
    if($_ =~ /POST/) { $hash{$ip}{"POST"}++; }
    if($_ =~ /PUT/) { $hash{$ip}{"PUT"}++; }
    if($_ =~ /DELETE/) { $hash{$ip}{"DELETE"}++; }
}
foreach $k (keys %hash)
{
    print "$k: GET=$hash{$k}{'GET'},POST=$hash{$k}{'POST'},PUT=$hash{$k}{'PUT'},DELETE=$hash{$k}{'DELETE'}\n";
}

【讨论】:

  • perl prog.pl
  • @SaketKumar 如果它有效,请选择我的答案作为正确的解决方案,以便其他有同样问题的人也可以使用它。谢谢
  • 总是 use strict; use warnings;
猜你喜欢
  • 1970-01-01
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
相关资源
最近更新 更多