Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Perl substitution not working

by Anonymous Monk
on Jun 21, 2012 at 00:23 UTC ( #977513=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

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 = <FH>; 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

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

Comment on Perl substitution not working
Select or Download Code
Re: Perl substitution not working
by 2teez (Priest) on Jun 21, 2012 at 00:40 UTC

    How does your input look like? Why slurp your whole file into an array, only to iterate later, in order to inter- change or ( do substitution ) on the array indexes. Am sure there are better ways of achieving your aim using a while loop with the open function.
    You can try y/,,,/,/s like so:

    my $value='Wed,Jun,13,10:23:35,2012,,,rdy,769,busy,31,rd,0,wr,22,ka, +6 '; $value=~y/,,,/,/s; print $value; ## Wed,Jun,13,10:23:35,2012,rdy,769,busy,31,rd,0,wr, +22,ka,6

    If I may suggest the following, use open function three argument, check if the open function fails and always close open file handler as soon as possible like so:

    open my $filehandler,'<',$file or die "can't open file: $!"; # .... others codes close $filehandler or die "can't close file:$!";

Re: Perl substitution not working
by frozenwithjoy (Curate) on Jun 21, 2012 at 00:44 UTC
    Well, the good news is that s/,,,/,/g should definitely work. The bad news is that your script is doing something weird. :P A couple things to be aware of:
    • you don't need to make @line an array. You can just write something like foreach my $line (@data).
    • you are using $line for both foreach loops. You are trying to use the same namespace for two different things. Maybe change the second one to foreach my $L1_line split...
    • Disregard this: The actual reason you aren't substituting properly is that you are printing @L1, but that array never gets modified by your substitution which acts on $line.

      The actual reason you aren't substituting properly is that you are printing @L1, but that array never gets modified by your substitution which acts on $line.

      Not true:

      my @L1 = qw(Abc aBc abC); for my $line (@L1) { $line =~ s/a/_/i; print "\@L1: <", join(", ", @L1), ">; \$line: <$line>\n"; } __END__ @L1: <_bc, aBc, abC>; $line: <_bc> @L1: <_bc, _Bc, abC>; $line: <_Bc> @L1: <_bc, _Bc, _bC>; $line: <_bC>
Re: Perl substitution not working
by muba (Priest) on Jun 21, 2012 at 00:45 UTC

    My guess? Because the commas are each part of another element of @L1, because they had "notice", "[", "mpmstats:", or "\t" inbetween them.

    Try this fix:

    # ... if ( ($line =~ /notice/) && ($line =~ /rdy/) ) # Spaces to commas $line =~ s/ /,/g; # Get rid of "notice", "[", "mpmstats:", and tabs inside the line. $line =~ s/notice|\[|mpmstats:|\t//g; # Change the dreaded Triple Comma into the nice and smooth Single +Comma. $line =~ s/,,,/,/g; # Or even the following if you want to replace all multiple subs +equent commas by # just one: # $line =~ s/,,+/,/g; # Show me what I've got print $line; }

    See how I wrote your [[] as \[? I think it's more readable that way. Also, regular expression understand \t just fine. There's no need to put it into a character class. And if ( ($line =~ /notice/) && ($line =~ /rdy/) ) { pretty much does the same thing as your two if statements. The inner parens are optional, but I prefer to write it that way.

Re: Perl substitution not working
by syphilis (Canon) on Jun 21, 2012 at 00:48 UTC
    Why is the s/,,,/,/g; not substituting the single comma?

    I think one possibility is that the three commas are spread over two adjoining elements of @L1.
    If the 3 commas don't belong to the same $line, the regex won't remove them.
    Try print "@L1"; so you can see whether the 3 commas belong to the same $line.

    Cheers,
    Rob
Re: Perl substitution not working
by Lotus1 (Chaplain) on Jun 21, 2012 at 00:50 UTC

    Here is what the code you posted will actually output:

    Global symbol "$line" requires explicit package name at 977513.pl line + 11. Global symbol "$line" requires explicit package name at 977513.pl line + 12. Global symbol "$line" requires explicit package name at 977513.pl line + 13. Global symbol "$line" requires explicit package name at 977513.pl line + 14. Global symbol "$line" requires explicit package name at 977513.pl line + 15. Global symbol "$line" requires explicit package name at 977513.pl line + 16. Global symbol "$line" requires explicit package name at 977513.pl line + 17. Execution of 977513.pl aborted due to compilation errors.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://977513]
Approved by muba
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (8)
As of 2014-08-28 08:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (259 votes), past polls