通过逐行读取文件来计算文件中字符串出现的次数并打印行数

时间:2019-07-16 08:40:56

标签: perl

当我为第一次迭代执行代码时,它工作正常,但对于其他迭代,则不会进入for($ row = 0; $ row =; $ row ++)循环。 所以我没有得到预期的结果。请帮忙。

@names =("error1","error2","error3");
my $filepath
="/home/acerun.log";
my $filepath1="/home/Perl/result6.log";
chomp($str);
open my $file,'<',$filepath or die "unable to open file :$!";
open my $file1,'>>',$filepath1 or die "unable to write to file :$!";
$count=0;
@line_num =();
@name=();
@number=();
foreach $str (@names){
  push(@name,$str);
  $i=0;
 for($row=0;$row=<$file>;$row++){
    chomp($row);
    if($row=~/$str/){
       push(@line_num,$.);     
       # print $file1 "$row \n";
       $i++;
       $count=1;
    }
    }
  push(@number,$i);
}

format Logfile = 
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<   @######               
 $Error_name                            $Number               
-----------------------------------------------------------
.

format Logfile_Top = 
-----------------------------------------------------------
Error_type                    number_of_times
----------------------------------------------------------- 
.
select($file1);
$~=Logfile;
$^=Logfile_Top;

$j=0;
foreach (@name){
    $Error_name = $_;
    $Number=$number[$j++];
    write;
}

预期结果:

-----------------------------------------------------------
Error_type                    number_of_times
-----------------------------------------------------------
error1                   36
-----------------------------------------------------------
error2                   35
-----------------------------------------------------------
error3                    17
-----------------------------------------------------------

实际结果:

-----------------------------------------------------------
Error_type                    number_of_times
-----------------------------------------------------------
error1                   36
-----------------------------------------------------------
error2                   0
-----------------------------------------------------------
error3                    0
-----------------------------------------------------------

2 个答案:

答案 0 :(得分:2)

从不会为第一个(error2error3)之后的名称输入内部循环,因为从查找第一个(error1)开始该文件已处于EOF状态。

您可以重新打开每个名称的文件,但是遍历每一行的名称而不是读取每个名称的文件要容易得多,而且快捷得多。

以下内容可解决此问题和其他问题:

use strict;    # Always use this!!!
use warnings;  # Always use this!!!

my @names = qw( error1 error2 error3 );

my %counts = map { $_ => 0 } @names;
while (my $line = <>) {
   chomp($line);
   for my $name (@names) {
      ++$counts{$name} if $line =~ /\Q$name/;
   }
}

print(
   #12345678901234567890123456789 12345678901234567890123456789
   "-----------------------------------------------------------\n",
   "Error_type                    number_of_times\n",
   "-----------------------------------------------------------\n",
);

for my $name (@names) {
   printf("%-29s %29s\n", $name, $counts{$name});
}

答案 1 :(得分:0)

C风格的for循环是错误的,您将$ row与两个不同的用途混为一谈,既是数字line number counter,又是从文件句柄读取的行。您需要分开目的。改用:

while (my $row = readline $file) {
    print $row;                         # line from file
    print $file->input_line_number;     # current line number of handle
}