Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Reducing a line read into $_

by mr_leisure (Beadle)
on Jan 04, 2001 at 14:48 UTC ( #49731=perlquestion: print w/replies, xml ) Need Help??

mr_leisure has asked for the wisdom of the Perl Monks concerning the following question:

Hi. Me Again. I am reading a text file and hoping to catch errors in it, and then send the error via an sms script i have to a mobile phone. The problem is, I would like to cut the line short. It may be easier to look at the code below...
#!/sbcimp/run/pkgs/gsbl/bin/perl -w open (LOG,"commandpost.log) || die "Could not open file!\n"; foreach (<LOG>) { if ($_ =~/CRITICAL/) { print $_; exec(" -msg=$_"); } else { } }
The commandpost.log file has the following contents :
[Thu Jan 4 00:09:38 2001 27068]ln4p47dbs:Global_One:smartCopy:MAJOR:C +all x84240 Couldn't copy STDERR to /gsbl3/UKCOPY/STDERR; Value too la rge for defined data type [Thu Jan 4 07:01:27 2001 1327]ln4p47dbs:Global_One:new_regext:CRITIC +AL:Call x84240 Unable to put file; /global1/Global120010103.DAT_tmp [Thu Jan 4 07:01:27 2001 1327]ln4p47dbs:Global_One:new_regext:MAJOR: +Call x84240 Failed to transfer /global1/data/G1PRD/regext/UKWARB/Glob al1.20010103.DAT to FCDREG_NT [Thu Jan 4 08:04:36 2001 8489]ln4p47dbs:Global_One:rebook:MAJOR:Call + x84240 WARNING; GetOptions() error
So the output from print is :
[Thu Jan 4 07:01:27 2001 1327]ln4p47dbs:Global_One:new_regext:CRITIC +AL:Call x84240 Unable to put file; /global1/Global120010103.DAT_tmp
Which should also become the -msg that is sent to the sms script. The problem is, the message is too long, so I was wondering how to cut some info out of the message? Perhaps the date and time in the square brackets(Thu Jan 4 07:01:27 2001 1327), as this will be re-applied on the sms message? Any ideas you guys have will be greatly appreciated. Thanks, ml.
if ($mr_leisure) { bow; }
this is still not finished

Replies are listed 'Best First'.
Re: Reducing a line read into $_
by davorg (Chancellor) on Jan 04, 2001 at 14:56 UTC

    You could reduce the length of the string in a "brute force" way using substr. For something more elegant, you'd probably need regexen. Here's an example which deletes the date as you suggested.


    For more info on this kind of thing you should read perlre and perlop.


    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

Re (tilly) 1: Reducing a line read into $_
by tilly (Archbishop) on Jan 04, 2001 at 18:05 UTC
    This is a comment on your coding style, not your question.

    All of your dies are uninformative. You will head a lot of future headaches off at the pass if you take a page from perlstyle and start working like this:

    my $logfile = "commandpost.log"; open (LOG, "< $logfile") or die "Cannot read $logfile: $!";
    (Incidentally I noticed a syntax error in your code there as well.) The point being to make sure that if something goes wrong you have enough information to be able to track down the problem.
Re: Reducing a line read into $_
by salvadors (Pilgrim) on Jan 04, 2001 at 17:05 UTC
    As well as everything that's been said already, you don't need to use $_ explicitly very often. Usually when you see $_ actually mentioned, you can remove it. You don't need it, for instance in a pattern match or substitution, or as the sole argument to print:
    foreach (<LOG>) { if ($_ =~/CRITICAL/) { print $_; }
    can just as easily be:
    foreach (<LOG>) { if (/CRITICAL/) { print; } }

    Beginning perl programmers tend to like to leave $_ in explicitly, so they can see what they're doing, but it's generally better to leave it out and learn to read it implicitly yourself.


Re: Reducing a line read into $_
by I0 (Priest) on Jan 04, 2001 at 14:56 UTC
      One fast question from acolyte: why's there "?" in your regexp?
      I wrote s/^\[.*\]//; and it works, so what gives us this question mark? or this is no difference?
      -- Daniellek

        The '?' gives you non-greedy matching. It shouldn't matter on the data that we've been shown, but if there's a chance that the data will have another ']' character later in the string, then the '?' becomes essential. Compare these:

        $_ = '[Remove this] and nothing else'; s/\[.*\]//g; print; $_ = '[Remove this] and [nothing] else'; s/\[.*\]//g; print;

        and then try then again with the '?'.


        "Perl makes the fun jobs fun
        and the boring jobs bearable" - me

Re: Reducing a line read into $_
by clemburg (Curate) on Jan 04, 2001 at 17:54 UTC

    You might want to take a look at Lingua::EN::Squeeze.

    Alternatively, I would suggest coding up a hash mapping regex patterns (to recognize error messages in the file) to your own message codes (to save space and display only the information you need, e.g., a priority and a problem class).

    Christian Lemburg
    Brainbench MVP for Perl

Re: Reducing a line read into $_
by Fastolfe (Vicar) on Jan 05, 2001 at 01:20 UTC
    Your problem is that you are using exec in the single-argument form, which is a HUGE SECURITY PROBLEM, not to mention that it will have major consequences to your system if your log file contains legitimate commands following a semi-colon. Here is your code:
    exec(" -msg=$_");
    If we expand $_ to include that line of data, your command expands to this:
    exec(" -msg=[Thu Jan 4 07:01:27 2001 1327]ln4p47dbs:Gl +obal_One:new_regext:CRITICAL:Call x84240 Unable to put file; /global1 +/Global120010103.DAT_tmp");
    Note the presence of shell metacharacters (specifically, the semi-colon and brackets). The solution is to clean up your exec call:
    exec("/path/to/", "-msg=$_") or die "exec: $!";
    This form does not pass your string through any sort of shell, so meta-characters in this fashion are "safe", unless itself uses them in an unsafe fashion, in which case you're screwed again and need to fix that other script.

    If you're using in a number of scripts, you might be better off turning this Perl script into a real Perl module, and just use that module from within your other scripts. Going a step further, I think there are modules out there in existence for interacting with SMS services, so that might be another option to pursue.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://49731]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (1)
As of 2021-09-20 06:12 GMT
Find Nodes?
    Voting Booth?

    No recent polls found