与Perl中的文件处理程序和正则表达式进行模式匹配

时间:2012-08-22 21:19:28

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

从我之前提出的一个问题开始,我试图从两个文件中读取数据,然后逐行解析一个文件,寻找与另一个文件的每一行所包含的字符串匹配。第一个是日志文件,第二个是我的密钥文件。我决定使用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)

再次感谢所有人的帮助和耐心。 :)

2 个答案:

答案 0 :(得分: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++;
    }
  }
}

答案 1 :(得分:0)

如果我理解正确的话,我不是百分百肯定的 如上所述,您可以使用“grep”非常简单地完成此操作 2个柜台的目的是什么?

这是perl的一个例子。

Inputfile中:

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;