【问题标题】:Pattern matching with filehandlers and regular expressions in PerlPerl 中文件处理程序和正则表达式的模式匹配
【发布时间】:2012-08-22 21:19:28
【问题描述】:

继我之前提出的一个问题之后,我试图从两个文件中读取数据,然后逐行解析一个文件,以匹配另一个文件每一行中包含的字符串。第一个是日志文件,第二个我将调用我的密钥文件。我决定使用 foreach 循环遍历密钥文件,然后将其嵌入其中,一个 while 循环将逐步遍历日志的每一行。我正在尝试使用模式匹配来识别特定的字符串,但是这个字符串要么被两个加号(即+name+)包围,要么被一个加号和一个星号(即+name*)包围。不幸的是,我没有太多运气让模式匹配工作......我在下面包含了我的模式搜索代码段的主体:

foreach $element (@fr_array) {
open (LOGFILE, "<", $logname)  or die $!;
while (<LOGFILE>) { #While reading one line at a time from the log....
  chomp;
  $log_string = <LOGFILE>;
  if ($log_string =~ /\+$element\+/) {
     $fr_count++;
     print "Counter increment since $log_string is the same as $element.";
     $log_match++;
     }
  }

编辑

感谢大家的反馈...我调用的几个命令用于帮助我跟踪程序并找到问题...我接受了一些建议,经过更多研究后,我尝试改用 grep 命令,但模式匹配似乎仍然无法正常工作。无论我使用什么作为搜索字符串,它似乎都被解析为真的。我整天都在查看代码,但我也不太确定从这里去哪里。在使用正则表达式失败后,我决定使用不同的搜索字符串,这个字符串由除了几个等号之外的所有文字组成。现在,澄清一下,一旦找到匹配项,我就不想对它们做任何事情,我只需要跟踪有多少匹配项,因此我使用了计数器。无论如何,我将包含我现在所在位置的更新代码段。我已经确认我的循环工作正常,这只是模式匹配的问题。我现在得到结果,但数字不准确....我的测试日志应该只返回 1 或 2,但它向我吐出 204。

open (LOGFILE, "<", $logname)  or die $!;
while($log_string = <LOGFILE>) {
   chomp $log_string;
   foreach $element (@fr_array) {
      $fr_count++ if (grep {"Action=123 Cls=AM"} $log_string)

再次感谢大家的帮助和耐心。 :)

【问题讨论】:

  • 你试过'grep -f key_file log_file'命令吗?你在 perl 中做同样的事情。
  • 您的代码会出现问题,因为您尝试OPEN 一个已经不是CLOSEd 的文件。如果您确实关闭了循环内的文件,它将从头开始读取(类似于seek)。
  • 好的,我想我知道它在做什么,虽然我不太确定如何更正它....我的带有 ID 的测试文件有 103 个条目,因此将从 0 开始递增,总共 102,并且条目只显示两次,因此 102 * 2 = 204。所以它正在定位它们,但每次找到一个 ID 时,它都会增加我的计数器的 ID 总数。

标签: regex perl grep pattern-matching file-handling


【解决方案1】:

正如我在评论中指出的那样,您正在尝试在 perl 中模拟“grep -f key_file log_file”命令。看看这个 grep 命令能不能帮到你。

对于这个 perl 代码,您尝试打开 @fr_array 中每个元素的文件。它不是必需的,并且使代码效率低下。此外,您在需要更正的 while 循环中读取 LOGFILE 两次。可以像下面这样阅读示例代码。注意 + 或 * 可以通过正则表达式中的 [\+\*] 匹配。

open (LOGFILE, "<", $logname)  or die $!;
while(my $log_string = <LOGFILE>) {
  chomp $log_string;
  foreach $element (@fr_array) {
    if ($log_string =~ /\+$element[\+\*]/) {
      $fr_count++;
      print "Counter increment since $log_string is the same as $element.";
      $log_match++;
    }
  }
}

【讨论】:

    【解决方案2】:

    我不能 100% 确定我是否正确理解了这个问题。
    如上所述,您可以使用“grep”非常简单地做到这一点。
    这两个计数器有什么用途?

    这是一个 perl 的例子。

    输入文件:

    123456789abc
    234567890abc
    345678901abc
    bla+bteam+bla
    456789012abc
    567890123abc
    678901234abc
    +cteam*
    789012345abc
    +ateam*
    890123456abc
    901234567abc
    012345678abc
    

    perlcode:

    #!/usr/bin/env perl
    use strict;
    
    my @tags = ("ateam","bteam");
    
    open LOGFILE, "< inputfile.txt" or dir $!;
    my @input = <LOGFILE>;
    close LOGFILE;
    
    my ($fr_count, $log_match) = 0;
    map { 
        chomp;
        foreach my $tag (@tags) { 
            /\+$tag[\+\*]/ && do { 
                print "Counter increment since $_ is the same as $tag.\n";
                $fr_count++; $log_match++;
            }
        }  
    } @input;
    

    【讨论】:

      猜你喜欢
      • 2011-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 2017-06-12
      • 1970-01-01
      相关资源
      最近更新 更多