http://www.perlmonks.org?node_id=1017139

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

Hi Monk

I require a parsing help when parsing and extracting info from a file of following pattern. Please refer to the content in between the '###' boundaries below

####################
Users of spice (total 20 licenses issued; total 0 license in use)
Users of runner (total 10 licenses issued; total 0 license in use)
Users of monitor(total 10 licenses issued; total 2 license in use)
Alex,Mon 20 Jan 2013
Peter,Wed 26 Jan 2013
Users of report (total 15 licenses issued; total 0 license in use)
Users of galaxy(total 10 licenses issued; total 3 license in use)
Martin,Fri 22 Jan 2013
Alex,Mon 21 Jan 2013
Peter,Wed 24 Jan 2013
######################

The file content shows how many licenses for some tools (spice,ruuner,monitor,galaxy) are issued,how many are in use and who all are using if in use.

My task is to extract the info for a given username (say Alex), which all licenses are in use and their availability. If no license is used for that user, then give nothing.

Please help me how can I extract that info for a user only when some licenses are in use.

I have tried to come up with this following code, but need help to go ahead :

while (<FILE>) { if(/^Users of (\w+):/) { my $line = $_; my $licName = $1; my ($totalIssued,$inUse); if ($line =~ /total of (\d+) licenses issued/) { $totalIssued = $1 ; print "Total : $totalIssued \n"; } if ($line =~ /total of (\d+) licenses in use/) { $inUse = $1 ; print "In Use : $inUse \n"; } } }

Thanks.

Replies are listed 'Best First'.
Re: parsing help required
by choroba (Cardinal) on Feb 05, 2013 at 12:16 UTC
    Just go over the lines. If you see a tool, remeber the relevant information. If you see the user, report the remembered information:
    #!/usr/bin/perl use warnings; use strict; my $user = shift; my ($tool, $issued, $use); while (<DATA>) { if (my ($t, $i, $u) = /^Users of (.*?) ?\(total ([0-9]+) licenses +issued; total ([0-9]+) license/) { ($tool, $issued, $use) = ($t, $i, $u); } if (/^$user,(.*)/) { print "Using $tool since $1 (issued $issued, in use $use)\n"; } } __DATA__ Users of spice (total 20 licenses issued; total 0 license in use) Users of runner (total 10 licenses issued; total 0 license in use) Users of monitor(total 10 licenses issued; total 2 license in use) Alex,Mon 20 Jan 2013 Peter,Wed 26 Jan 2013 Users of report (total 15 licenses issued; total 0 license in use) Users of galaxy(total 10 licenses issued; total 3 license in use) Martin,Fri 22 Jan 2013 Alex,Mon 21 Jan 2013 Peter,Wed 24 Jan 2013
    BTW, is the space after galaxy really missing? If no, you can remove the question marks from the regex.
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Thank you, it helped
Re: parsing help required
by sundialsvc4 (Abbot) on Feb 05, 2013 at 13:51 UTC

    One very nice feature of Perl that can help here (which of course is why it’s here ...) is called autovivification:   “to come to life automatically.”   It lets you write code like this:

    $$usercounts{$name} += $howmany; ...
    (or equivalently: $usercounts->{$name} += $howmany; ...)

    ... and simply not have to worry about whether the hashref $usercounts already contains an entry for $name.   If it does, cool.   But if it doesn’t, an entry is automagically created for you with an initial value of zero (because Perl knows that you’re going to add something to it).   Then, either way, the addition operation happens and life is good.

    One of the things that I definitely like about this language is its pragmatism.   It’s a tool for the job, designed and built by people who had a job to do.   Maybe in a few cases it tips a bit too far in the name of “DWIM = Do What I Mean,” but generally it’s both powerful and expressive, both in a practical way.

Re: parsing help required
by vinoth.ree (Monsignor) on Feb 05, 2013 at 12:25 UTC

    In your code \d+ will match the users with 0 licenses in use. because \d matches 0-9.