PRATEEK MISHRA
PRATEEK MISHRA

Reputation: 11

count number of times and print line number of occurence of a string in a file by reading that file line by line

when I am executing my code for first iteration it is working fine,but for other iteration it is not going into the for($row=0;$row=;$row++) loop. so I am not getting the expected result .Please help.

@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;
}

expected result:

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

actual result:

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

Upvotes: 0

Views: 68

Answers (2)

ikegami
ikegami

Reputation: 385645

The inner loop is never entered for the names after the first one (error2 and error3) because the file is already at EOF from looking for the first one (error1).

You could re-open the file for every name, but it's far simpler and faster to loop over the names for every line instead of reading the file for every name.

The following fixes this and other issues:

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});
}

Upvotes: 2

daxim
daxim

Reputation: 39158

The C style for loop is wrong, you mix up $row with two different purposes, as both numeric line number counter and as a line read from the file handle. You need to separate the purposes. Use instead:

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

Upvotes: 0

Related Questions