Beginner am Montag, 26. Februar 2007 17:02:
> On 26 Feb 2007 at 15:58, D. Bolliger wrote:
> > Beginner am Montag, 26. Februar 2007 14:50:

Hi

> > > I am trying to parse some dhcp-lease files to extract the ip, mac and
> > > hostname.
> > >
> > > I am struggling to get either, the regex of the $/, correct. I am not
> > > sure which combination of these I should use.
> > >
> > > There is some sample data and my best effort below. Can anyone offer
> > > any pointers?

> > > ======= Sample Data =========
> >
> > lease 196.222.237.209 {
> >   starts 5 2007/02/23 17:53:57;
> >   ends 6 2007/02/24 17:53:57;
> >   binding state active;
> >   next binding state free;
> >   hardware ethernet 00:60:04:28:28:01;
> >   client-hostname "lab.mydomain.com";
> >
> > > ============== My effort ===========
> > > #!/usr/bin/perl
> > >
> > > use strict;
> > > use warnings;
> > >
> > > my $file = '/var/lib/dhcp3/dhcpd.leases';
> > > my ($ip,$mac,$host);
> > >
> > > #$/ = "}\n";
> >
> > used below :-)
> >
> > > $/ = '';
> > >
> > > open(FH,$file) or die "Can't open $file: $!\n";
> > >
> > > while (<FH>) {
> > >         chomp;
> > >         ($ip,$mac,$host) = ($_ =~
> > > /lease\s+(\d{3}\.\d{3}\.\d{3}\.\d+).*thernet\s+(\d{2}:\d{2}:\d{2}:\d{2
> > > }:\d{2}:\d{2}).*ostname\s+\
> > > "(\w+\.scien.*)"/smg);
> > >
> > >         print "$ip $mac $host\n";
> > >
> > > }
[snipped]

> Thanx Dani,
>
> That's worked a treat. Just to complete the learning curve, where was
> I going wrong?

That should have been part of my first answer, sorry. I'll try and hope I 
don't mess with the test versions and the english language :-)

Looking at the regex: 

It only matches MACs without a-c hex digits (and there's no 'scien' string in 
the data, but that's probably due to the altered hostnames, and I assume that 
the \d{3} in the IP matching part is intended.).

In the script version with $/ = '':

This reads all records at once, and this seems to be the reason why you used 
the /g modifier. But then, after matching the IP of the first lease, the 
first .* will skip all leases except the last one for the mac/host matching.
   So you (or I respectively) get a single wrong result with the IP of the 
first lease and mac/host of the last lease (after correcting the mac regex 
part).
   So you would have to alter the .* into the non-greedy .*? (to avoid 
skipping leases) and also append a .*? at the end of the regex to match what 
is "between the leases" [argh!] (to avoid only one match).

But even if the regex is correct, and the ip/mac/host of every lease is 
matched, only the first 3 captured matches get stored into ($ip,$mac,$host), 
and the others are discarded (which would not be the case with 
@data=/....../g).

When you tried with $/ = "}\n":

I don't know neither how the regex looked like in this case, nor what went 
wrong then, so I can't say much.

Other notes:

The $_=~ is not necessary, because if the left side of =~ is missing, $_ is 
used by default.

To read all leases, you could also do it like so to avoid the somehow 
misleading while loop:
{
  local $/;      # sets $/ to undef
  my $data=<FH>; # slurp entire file
  # ...match with /g modifier...
}

chomp is not necessary.

Hope that covers the most important issues :-)

Dani

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to