0

我正在编写一个脚本来查看 access_log 文件,以查看每个搜索引擎被访问了多少次,以及哪个搜索引擎被访问最多。我确信我的某些语法存在问题,但我什至无法判断,因为在运行它时我没有收到任何信息。任何帮助,将不胜感激!

代码:

#!/usr/bin/perl

use 5.010;

$googleCount = 0;
$msnCount = 0;
$yahooCount = 0;
$askCount = 0;
$bingCount = 0;


while (<STDIN>)
{
    if (/(google.com)/)
    {
        $googleCount++;
    }

    if (/(msn.com)/)
    {
        $msnCount++;
    }

    if (/yahoo.com/)
    {
        $yahooCount++;
    }

    if (/ask.com/)
    {
        $askCount++;
    }

    if (/bing.com/)
    {
        $bingCount++;
    }
}



print "Google.com was accessed $googleCount times in this log.\n";
print "MSN.com was accessed $msnCount times in this log.\n";
print "Yahoo.com was accessed $yahooCount times in this log.\n";
print "Ask.com was accessed $askCount times in this log.\n";
print "Bing.com was accessed $bingCount times in this log.\n";

我正在运行 MacOS。在我输入的终端中:

perl -w access_scan.pl access_log.1

当我按下回车键时,什么也没有发生。

4

4 回答 4

3

该脚本正在尝试从 STDIN 读取,但您提供了要从中读取的文件名作为参数。

“什么都没有发生”,因为脚本正在等待输入(由于您没有将任何内容重定向到标准输入,因此它希望您输入)。

更改<STDIN><>或将命令更改为perl -w access_scan.pl < access_log.1

于 2013-02-13T17:34:22.817 回答
3

除了您的脚本没有按预期工作之外,您的脚本还有一些问题:

在正则表达式中,点.匹配任何非换行符。这包括文字句点,但不限于此。要么转义它 ( ) 要么用:/google\.com/保护特殊字符。\Q...\E/\Qgoogle.com\E/

有一句编程谚语“三个或更多,使用一个for”。循环中的所有条件都是相同的,除了正则表达式。您的计数实际上是一个变量。您最后的报告多次出现在同一行。

您可以使用哈希来减轻痛苦:

#!/usr/bin/perl
use strict; use warnings; use feature 'say';

my %count;  # a hash is a mapping of strings to scalars (e.g. numbers)
my @sites = qw/google.com msn.com yahoo.com ask.com bing.com/;

# initialize the counts we are interested in:
$count{$_} = 0 foreach @sites;

while (<>) { # accept input from files specified as command line options or STDIN
  foreach my $site (@sites) {
    $count{$site}++ if /\Q$site\E/i; # /i for case insensitive matching
  }
}

foreach my $site (@sites) {
  say "\u$site was accessed $count{$site} times in this log";
}

大写的\u下一个字符,这是产生相同输出所必需的。
say完全相同print,但附加了一个换行符。它在 perl5 v10 或更高版本中可用。

于 2013-02-13T19:47:35.733 回答
0

您的脚本正在从标准输入读取,但您将输入作为文件提供。您需要重定向

perl -w access_scan.pl < access_log.1

< file构造提供文件的内容作为脚本的标准输入。

于 2013-02-13T17:33:54.593 回答
0

该脚本运行良好(我对其进行了测试),但您需要将其与 STDIN 中的日志一起提供:

cat access_log.1 | perl -w access_scan.pl
于 2013-02-13T18:07:31.557 回答