【问题标题】:Perl - How to search the iteration of a line (from the same text) in a textPerl - 如何在文本中搜索行的迭代(来自相同的文本)
【发布时间】:2013-10-20 23:00:52
【问题描述】:

[已解决] 提前为我的错误代码道歉(我是 Perl 新手)。 我需要编写一个脚本来搜索文件中的某一行文本(它必须包含单词“authentication failure”和形式为“user=username”的用户名)并查找包含相同用户名的行的可能迭代以及当天记录的“认证失败”。日期和月份是我正在分析的文本每行的前两个单词。因此,每一行都类似于:

"Jun 24 bla bla bla authentication failure bla bla bla user=mickey_mouse"

不管我的目标是什么,我确信问题在于我对 Perl 缺乏经验。所以请看看我的代码并告诉我是否有问题。

这是我到目前为止写的代码

#!usr/bin/perl
if (!defined($ARGV[0]) or !defined($ARGV[1])) {
    die "\nMissing arguments.\n";
}
open(FILE,$ARGV[0]) or die "Cannot open log file";
open(FILE1,$ARGV[0]) or die "Cannot open log file";

foreach $line(<FILE>) {
    chomp;
    if($line=~/authentication failure/ and $line=~/ user=/) {
        $count = 0;
        @chops = split("=", $line);
        $currentUser = $chops[-1];
        chomp($currentUser);
        @chops1 = split(" ", $line);
        $currentDate = $chops1[0]." ".$chops1[1];
        chomp($currentDate);
        print "\nUSER: $currentUser DATE: $currentDate\n";
        foreach $line1(<FILE1>) {
            chomp;
            if(index($line1, $currentUser) != -1 and 
               index($line1, $currentDate) != -1 and 
               $line1 =~ /authentication failure/) {
                $count++;
                print $count;
                if(count>=2) {
                    push($currentUser,@authenticFails);
                    last;
                }   
            }
        }
    }

}

print @authenticFails;

close(FILE);
close(FILE1);

[已解决] 感谢 sputnick 的回答和建议。无论如何,我弄清楚我的问题是什么。我只需要在嵌套的 -for- 块内(而不是在两个 fors 之前)编写第二个 open(ARGV[0]) 东西并在退出之前将其关闭。对于我正在使用第一个 -for- 块分析的每一行,这是重新开始对文件的每一行进行迭代的唯一方法。

再次感谢各位。

【问题讨论】:

  • 你为什么不使用 grep -i -r "authentication failure" filename.txt 和类似的用户名
  • push($currentUser,@authenticFails) -- 混淆了参数的顺序。这是一个致命错误,不能出现在您运行的代码中。永远不要发布不是您正在运行的实际代码的代码。这只是浪费我们的时间。
  • 是的,我也发现了。不过谢谢。 :)
  • 你为什么要检查FILE 中的每一行与FILE1 中的每一行?另外,这段代码不会导致部分匹配,例如将Jun 1Jun 10 匹配,将user=foofoobar 匹配?用户 cat 将收到大量身份验证失败匹配,因为该名称匹配 authentiCATion

标签: perl file


【解决方案1】:

我会使用 菱形运算符 &lt;&gt; 和哈希来计算出现次数:

use Modern::Perl; # enable strictures and features like "say"

my %hash;
# looping line by lines over the files
while (my $line = <ARGV>) {
    if ($line =~ /^(\w+\s+\d+)\s+.*?authentication\s+failure.*?user=(.*)/) {
        $hash{"$2|$1"}++;
    }
}
foreach my $key (keys %hash) {
    my ($user, $day) = split /\|/, $key;
    say "$hash{$key} auth failures for $user on $day";
}

输出

3 auth failures for mickey_mouse on  Jun 24
1 auth failures for mickey_mouse on  Jun 23
1 auth failures for xxx on  Jun 21

注意事项

  • 始终输入use strict; use warnings;use Modern::Perl
  • 如果您打开文件,请以正确的方式进行操作:open my $fh, "&lt;", "file" or die $!,您甚至可以通过添加 use autodie 来省略 or die,就像 Dadid W 建议的那样。

【讨论】:

  • 为什么不加use autodie;
猜你喜欢
  • 2015-07-20
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-19
相关资源
最近更新 更多