I am attempting to remove 3 commas from the file below but it is not working.

#!/usr/bin/perl

use strict;
use warnings;

my @data;
my @line;

open(FH, "error_log");
@data = 

foreach $line (@data) {
   if ($line =~ /notice/) {
      if ($line =~ /rdy/) {
        $line =~ s/ /,/g;
        my @L1 = split(/notice|[[]|mpmstats:[\t]/, $line);
        foreach $line (@L1) {
           $line =~ s/,,,/,/g;
           print @L1;
           }
        }
     }
  }

My output is as follows.
Wed,Jun,13,10:23:35,2012,,,rdy,769,busy,31,rd,0,wr,22,ka,6
Wed,Jun,13,10:42:57,2010,,,rdy,758,busy,41,rd,0,wr,54,ka,5

Why is the s/,,,/,/g; not substituting the single comma?

Dani AI

Generated

Short diagnosis for : the replacement you used only matches exactly three consecutive commas, so it will miss runs of two, four, or more. That plus printing the whole array inside the inner loop and reusing the same $line variable are the likely causes of the surprising output. is right to flag the repeated print @L1 behavior, and correctly pointed out that the file read line (@data = <FH>) and proper looping are important. A more robust approach is to (1) read each line safely, (2) normalise runs of whitespace to a single comma if you converted spaces earlier, and (3) collapse any run of multiple commas into one.

Example pattern to use (read line-by-line, then normalise and collapse runs):

use strict;
use warnings;

open my $fh, '<', 'error_log' or die "open: $!";
while (my $line = <$fh>) {
    chomp $line;
    $line =~ s/\s+/,/g;     # turn runs of whitespace into a single comma
    $line =~ s/,{2,}/,/g;   # collapse two-or-more commas to one
    print "$line\n";
}
close $fh;

Quick troubleshooting checklist:

  • Ensure @data = <FH>; (or a proper while loop) actually reads the file.
  • Avoid reusing the same scalar name for nested loops; use foreach my $part (@L1) or distinct names so you don't clobber outer values.
  • Don’t print the whole array every iteration; print the current element or join and print once.
  • If the input is real CSV (empty fields matter), parse with Text::CSV instead of collapsing commas, since collapsing can lose intended empty fields.

Recommended Answers

All 2 Replies

This looks odd to me:

foreach $line (@L1) {
    $line =~ s/,,,/,/g;
    print @L1;
}

Sure you want to print all of @L1 every time through that loop?

As for your output, I can't tell what you expect it to do. Could you post your input and describe what you expected to happen?

Hi rupes0610,

Check the following:
Check your line 10, you probably omited something like:

@data = <FH>;

You didn't close the open file handler, neither did you test for failure.
I also think line 19, should be something like:

print $line;

not

 print @L1;

Moreover, I believe you can do all of these within a single while loop in an open function with no need to slurp all your input into array variable.
Show your input then let's have fun!

However, if you must have your code just like what you gave above. You can still achieve your aim by using tr///s like so:

#!/usr/bin/perl
use warnings;
use strict;

 while(<DATA>){
    chomp;
    tr/,,,/,/s;
   print $_,$/;
 }

__DATA__
Wed,Jun,13,10:23:35,2012,,,rdy,769,busy,31,rd,0,wr,22,ka,6
Wed,Jun,13,10:42:57,2010,,,rdy,758,busy,41,rd,0,wr,54,ka,5

OUTPUT:
Wed,Jun,13,10:23:35,2012,rdy,769,busy,31,rd,0,wr,22,ka,6
Wed,Jun,13,10:42:57,2010,rdy,758,busy,41,rd,0,wr,54,ka,5

This is Perl, you can make anything possible, but you also have to live with them!
Enjoy, hopes this help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.