Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Perl substitution not working

by Anonymous Monk
on Jun 21, 2012 at 00:23 UTC ( [id://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?

Replies are listed 'Best First'.
Re: Perl substitution not working
by syphilis (Archbishop) 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 2teez (Vicar) 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 Lotus1 (Vicar) 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.
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 frozenwithjoy (Priest) 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>

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
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?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2024-04-19 03:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found