in reply to Re^5: String Matching
in thread String Matching

Below is the full code. The odd thing is its running on my ubuntu box - I am sure there is a syntax error I am blind to here but then why is no problem reported under ubuntu

steveb@laptop:~/Loading_Scripts$ perl -c syslog_smtp.pl syslog_smtp.pl syntax OK

On the Solaris box

bash-3.00# perl -c ./syslog_smtp.pl Unrecognized escape \S passed through at ./syslog_smtp.pl line 38. Unrecognized escape \s passed through at ./syslog_smtp.pl line 38. Unrecognized escape \s passed through at ./syslog_smtp.pl line 38. "my" variable $msgdate masks earlier declaration in same scope at ./sy +slog_smtp.pl line 53. "my" variable $msgtime masks earlier declaration in same scope at ./sy +slog_smtp.pl line 53. "my" variable $msgid masks earlier declaration in same scope at ./sysl +og_smtp.pl line 53. "my" variable $from masks earlier declaration in same scope at ./syslo +g_smtp.pl line 62. "my" variable $remainder masks earlier declaration in same scope at ./ +syslog_smtp.pl line 62. "my" variable $msgdate masks earlier declaration in same scope at ./sy +slog_smtp.pl line 63. "my" variable $msgtime masks earlier declaration in same scope at ./sy +slog_smtp.pl line 63. "my" variable $msgid masks earlier declaration in same scope at ./sysl +og_smtp.pl line 63. "my" variable $remainder1 masks earlier declaration in same scope at . +/syslog_smtp.pl line 63. "my" variable $csv masks earlier declaration in same scope at ./syslog +_smtp.pl line 66. Global symbol "$remainder1" requires explicit package name at ./syslog +_smtp.pl line 38. Global symbol "$csv" requires explicit package name at ./syslog_smtp.p +l line 38. Global symbol "$csv" requires explicit package name at ./syslog_smtp.p +l line 38. syntax error at ./syslog_smtp.pl line 52, near "my ( $from, $srvrip ) += $remainder =~ m/=>\s*(" (Might be a runaway multi-line ** string starting on line 38) syntax error at ./syslog_smtp.pl line 60, near "} elsif" syntax error at ./syslog_smtp.pl line 70, near "}" ./syslog_smtp.pl had compilation errors.
#!/usr/bin/perl # use strict; use warnings; my $no = 0; my %monthNos = map {$_ => ++$no} qw{ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov +Dec }; while (my $line = <STDIN>) { chomp($line); my ($mon, $day, $time, $loghost, $prog, $remainder) = split m{:?\s+}, $line, 6; my ($user) = $remainder =~ m{user=([^,]+)}; my ($rip) = $remainder =~ m{rip=([^,]+)}; my ($op) = $remainder =~ m{\s(==|<=|\*\*|\+\+)\s}; my $yr = 2012; my $srvrip = ''; my $from = ''; my $msgid = ''; my $msgdate = ''; my $msgtime = ''; $remainder =~ tr/"/'/; $_ //= '' for $user, $rip, $op, $srvrip, $from, $msgid, $msgdate, +$msgtime; # <= message arrival # => normal message delivery # -> additional address in same delivery # *> delivery suppressed by -N # ** delivery failed; address bounced # == delivery deferred; temporary problem if( $op eq '<=' ){ # message arrival my ( $from, $srvrip ) = $remainder =~ m/<=\s*(\S+)[^[]+\[([^\]]+)/ +; # <=\s* # (\S+) # Capture the email address following <= # [^[]+\[ # Skip to the first subsequent square bracket. # ([^\]]+) # Capture until a closing bracket. # /x; my ($msgdate, $msgtime, $msgid, $remainder1) = split m{:?\s+}, $remainder, 4; # DATETIME, SERVER, SEQNO, DATETIME1, MSGID, SENDER, RECIPIENT, SVRIP, + ORIGMSGID, STATUS, SUBJECT my $csv = sprintf q{%02d-%02d-%s %s,%s,,%s %s,%s,%s,,%s,%s,,"%s"}, $yr, $monthNos{$mon}, $day, $time, $loghost, $msgdate, $msgtime, $ +msgid, $from, $srvrip, $msgid, $remainder; print "$csv\n"; } elsif( $op eq '=>' ){ # normal message delivery my ( $from, $srvrip ) = $remainder =~ m/=>\s*(\S+)[^[]+\[([^\]]+)/ +; my ($msgdate, $msgtime, $msgid, $remainder1) = split m{:?\s+}, $remainder, 4; # DATETIME, SERVER, SEQNO, DATETIME1, MSGID, SENDER, RECIPIENT, SVRIP, + ORIGMSGID, STATUS, SUBJECT my $csv = sprintf q{%02d-%02d-%s %s,%s,,%s %s,%s,%s,,%s,%s,,"%s"}, $yr, $monthNos{$mon}, $day, $time, $loghost, $msgdate, $msgtime, $ +msgid, $from, $srvrip, $msgid, $remainder; print "$csv\n"; } elsif( $op eq '==' ){ # delivery deferred; temporary problem my ( $from ) = $remainder =~ m/==\s*(\S+)/; my ($msgdate, $msgtime, $msgid, $remainder1) = split m{:?\s+}, $remainder, 4; # DATETIME, SERVER, SEQNO, DATETIME1, MSGID, SENDER, RECIPIENT, SRVRIP +, ORIGMSGID, STATUS, SUBJECT my $csv = sprintf q{%02d-%02d-%s %s,%s,,%s %s,%s,%s,,,%s,,"%s"}, $yr, $monthNos{$mon}, $day, $time, $loghost, $msgdate, $msgtime, $ +msgid, $from, $msgid, $remainder; print "$csv\n"; } elsif( $op eq '**' ){ # fall back on a default behavior my ( $from ) = $remainder =~ m/\*\*\s*(\S+)/; my ($msgdate, $msgtime, $msgid, $remainder1) = split m{:?\s+}, $remainder, 4; # DATETIME, SERVER, SEQNO, DATETIME1, MSGID, SENDER, RECIPIENT, SRVRIP +, ORIGMSGID, STATUS, SUBJECT my $csv = sprintf q{%02d-%02d-%s %s,%s,,%s %s,%s,%s,,,%s,,"%s"}, $yr, $monthNos{$mon}, $day, $time, $loghost, $msgdate, $msgtime, $ +msgid, $from, $msgid, $remainder; print "$csv\n"; } else { my $csv = sprintf q{%02d-%02d-%s %s,%s,,,,,,,,,"%s"}, $day, $monthNos{ $mon }, $yr, $time, $loghost, $remainder; print "$csv\n"; } }

Replies are listed 'Best First'.
Re^7: String Matching
by davido (Cardinal) on Aug 14, 2012 at 22:39 UTC

    On line 26 you have the following:

    $_ //= '' for $user, $rip, $op, $srvrip, $from, $msgid, $msgdate, $msg +time;

    The //= operator was introduced in 5.10.0. As you mentioned, you're running this on a 5.8.x version of Perl. That's giving the compiler fits. Change that line to:

    $_ = defined ? $_ : '' for $user, $rip, $op, $srvrip, $from, $msgid, $ +msgdate, $msgtime;

    Or maybe a little more clarity:

    use constant EMPTY_STRING => q{}; # ..... foreach ( $user, $rip, $op, $srvrip, $from, $msgid, $msgdate, $msgtime + ) { $_ = EMPTY_STRING # Alias propagates to foreach list. if not defined $_; }

    Dave

      Hey, wait a minute... Hey, wait a minute... Hey, wait a minute...

        What's going on here?! Get off this frequency! (j/k)

        :)


        Dave

Re^7: String Matching
by AnomalousMonk (Archbishop) on Aug 14, 2012 at 22:36 UTC
    $_ //= '' for $user, $rip, $op, $srvrip, $from, $msgid, $msgdate, $msg +time; ### line 25

    A big problem here is that the  //= operator (and its pal  // 'defined-or') were not added until version 5.10 (AFAIR), so 5.8.4 is definitely not going to grok this. Try
        defined($_) || $_ = '' for ...;
    instead.