I guess I'll keep it on list since there seems to be some interest in
regular expressions (and I'm left wondering why this is deemed such
complicated code)

If I'm not mistaken, the code really just needed to be (minus error
handling) the following since all you cared about was the getty info. So
we will look at this as an example, only because it doesn't match anything
we don't care about (like the original because I wanted you to be able to
use that info if I was wrong about my assumptions)

open (FILE, "<file");
while (<FILE>) {        
        if ( /##### data dev=$ttydev, pid=$getty_id, caller='.*?',  
conn='(.*?)\/(.*?)\/(.*?)'/) {
              print "getty data: $1/$2/$3\n";
              last;
         }
}
close FILE;

rpjday covered reading a file line by line and $_ so I won't repeat that.

But what is this awfully compilcated looking stuff you say?

        if ( /##### data dev=$ttydev, pid=$getty_id, caller='.*?',  
conn='(.*?)\/(.*?)\/(.*?)'/) {

We are using the matching operator // (man perlop), and applying it to $_
which happens automatically so we don't need something like $line =~
//. Each line is examined, and if the regular expression between the //
matches, it returns true and we pass the if check.

The regular expression is not that difficult. The $ttydev and $getty_id
get expanded before the match, so it really looks like

/##### data dev=ttyC12, pid=13032, caller='.*?', conn='(.*?)\/(.*?)\/(.*?)'/

In this example. the only thing special about this is the .*? and the ()

.*?     .* matches zero or more characters. The ? just says don't be greedy
(which perl is by default) and will stop matching at the first ' instead
of all the way top the last tick of conn='' in the case of
caller='.*?'. If I had used .*, I would have gotten one match on
caller='.*?' and the value would have been everything from the ' to the
last ' on that line.

()      these capture whats in between them and store them in variables named
$1, $2 ... in the order they are found. You can even nest them. 

See man perlre for more info on these two

              print "getty data: $1/$2/$3\n";

here I just use the matches

              last;

This says once I find a match then fall out of the while loop - no sense
looping through any more lines than you need to .

         }

end of the if.

Now what was so complicated and 'clever' about that?

charles

On Tue, 22 Feb 2000, Robert Canary wrote:

> Hi Charles,
> 
> Hey thanks for your and everyones help on such an offtopic subject.  I have all of 
>the
> O'Reilly Perl books, but I something I never picked up on was the assignment of 
>values
> to the $1....7.  I am still sure how this works, but had I understood it before it
> would have made things allot esaier (and quicker perl code).
> 
> One quick question:  So anything that a pattern matches in a () is assigned to a
> $1...$9, is this a correct statement?  Since this post has now left the orginal
> textus, could you drop me a quick yes or no off the mail-list, if you have a spare
> moment.
> 
> Thanks agin :-)
> 
> Charles Galpin wrote:
> 
> > Hi Robert
> >
> > Boy you have really made this hard on yourself (and us) :)
> >
> > Why didn't you post this line
> >
> > 02/18 15:54:26 ##### data dev=ttyC12, pid=13032,
> > caller='none',conn='31200/LAPM/V42BIS', name='', cmd='/usr/sbin/pppd',
> > user='/AutoPPP/'
> >
> > and say that you know the pid and the dev, and need to get the other
> > fields when you match this line?
> >
> > My answer would (without all this fanfare) have been
> >
> > sub w1_connect_info {
> >     # This routine extract available info passed in the getty logs.
> >     # Here is a sample of the line we are looking for:
> >     # 02/18 15:54:26 ##### data dev=ttyC12, pid=13032, caller='none',
> > conn='31200/LAPM/V42BIS', name='', cmd='/usr/sbin/pppd', user='/AutoPPP/'
> >     my ($getty_id,$ttydev) = @_;
> >     my ($line,$item);
> >     my (@getty_line);
> >
> >     open (GETTYFILE, "</var/log/getty.log.$ttydev") || die "Can't open
> > log.$ttydev: $!";
> >     while (<GETTYFILE>) {
> >         if ( /##### data dev=$ttydev, pid=$getty_id, caller='(.*?)',
> > conn='(.*?)\/(.*?)\/(.*?)', name='(.*?)', cmd='(.*?)', user='(.*?)'/) {
> >              print "getty data: $2/$3/$4\n";
> >              print "other stuff you don't seem to care about: caller=$1
> > name=$5  cmd=$6 user=$7\n";
> >              last;
> >          }
> >     }
> >
> >     close GETTYFILE;
> >
> > } # sub w1_connect_info
> >
> > make sure you put a space before conn when you unwrap these lines.
> >
> > since the format is so well defined, you don't need to get fancy here
> > charles


-- 
To unsubscribe: mail [EMAIL PROTECTED] with "unsubscribe"
as the Subject.

Reply via email to