Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

beginner needs help

Status
Not open for further replies.

wpdavids

IS-IT--Management
Jan 31, 2001
60
US
Maybe someone can help me with this so I can be on my way learning perl. I gone through a couple books on perl; however, it's not exactly sinking in. Maybe if someone can help me with a script or two I will start understanding Perl.

I want to parse the contents of this file.



VOLUME GROUP: datavg VG IDENTIFIER: 000d94600000d600000001117031c111
VG STATE: active PP SIZE: 128 megabyte(s)
VG PERMISSION: read/write TOTAL PPs: 4789 (612992 megabytes)
MAX LVs: 256 FREE PPs: 274 (35072 megabytes)
LVs: 20 USED PPs: 4515 (577920 megabytes)
OPEN LVs: 20 QUORUM: 6 (Enabled)
TOTAL PVs: 11 VG DESCRIPTORS: 11
STALE PVs: 0 STALE PPs: 0
ACTIVE PVs: 11 AUTO ON: yes
MAX PPs per VG: 32512
MAX PPs per PV: 1016 MAX PVs: 32
LTG size (Dynamic): 1024 kilobyte(s) AUTO SYNC: no
HOT SPARE: no BB POLICY: relocatable



This is the script that I have so far.

#!/usr/bin/perl -w


$TheFile = "lsvg_datavg";
open(INFILE, $TheFile) or die "The file $TheFile could not be found \n";

while (<INFILE>) {
$TheLine = $_;
chomp($TheLine);

my @values = split(/[(;);]/, $TheLine);
my @line = grep(/VOLUME GROUP:/, "@values");
my @line1 = grep(/TOTAL PPs:/,"@values");
my @line2 = grep(/FREE PPs:/,"@values");


print "\n";
print "@line";
print "@line1";
print "@line2";


}


This is the current output.

VOLUME GROUP: datavg VG IDENTIFIER: 000d94600000d600000001117031c111

VG PERMISSION: read/write TOTAL PPs: 4789 612992 megabytes
MAX LVs: 256 FREE PPs: 274 35072 megabytes


This is the output I'm looking for.

VOLUME GROUP: datavg
TOTAL : 612992 MB
FREE : 35072 MB
USED : 577920 MB

 
Those seem to be fixed-width columns, so the 'unpack' function is your friend (it's a tricky one to get the hang of: have a look at perlpacktut if you're confused). By the way, when posting code (or indeed data), it helps to put them between [code][/code] tags, to preserve the spacing and indentation.

This will get the data you've posted into a hash. After that you can do what you like with it:
Code:
#!/usr/bin/perl -w
use strict;

my %data;

while(<DATA>) {
   for ( unpack ( 'A45A*', $_ ) ) {
      my ( $key, $value ) = split /:\s+/, $_;
      $data{$key} = $value if $key;
   }
}

print "$_: $data{$_}\n" for keys %data;

__DATA__
VOLUME GROUP:       datavg                   VG IDENTIFIER:  000d94600000d600000001117031c111
VG STATE:           active                   PP SIZE:        128 megabyte(s)
VG PERMISSION:      read/write               TOTAL PPs:      4789 (612992 megabytes)
MAX LVs:            256                      FREE PPs:       274 (35072 megabytes)
LVs:                20                       USED PPs:       4515 (577920 megabytes)
OPEN LVs:           20                       QUORUM:         6 (Enabled)
TOTAL PVs:          11                       VG DESCRIPTORS: 11
STALE PVs:          0                        STALE PPs:      0
ACTIVE PVs:         11                       AUTO ON:        yes
MAX PPs per VG:     32512
MAX PPs per PV:     1016                     MAX PVs:        32
LTG size (Dynamic): 1024 kilobyte(s)         AUTO SYNC:      no
HOT SPARE:          no                       BB POLICY:      relocatable
 
Since you say you are new and learning, I have written this in what I think is beginner level code. Well its really a little beyond beginner but then you are trying to do something that is not exactly beginner level programming. Using grep() is not the correct tool for this job. You need to write some regexp (see code below) that target the patterns you are looking for in the lines and extract just that information. Please do not ask me to explian the code line by line and symbol for symbol. You can read some regexp tutorials to try and understand the regexp stuff, they are not complex. I am not saying this is the best way to go about parsing the file but if I or someone were to code a really good way you might not learn much from it.

Code:
[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]strict[/green][red];[/red]
[black][b]use[/b][/black] [green]warnings[/green][red];[/red]
[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]@output[/blue][red];[/red]
[black][b]my[/b][/black] [blue]$TheFile[/blue] = [red]"[/red][purple]lsvg_datavg[/purple][red]"[/red][red];[/red]
[url=http://perldoc.perl.org/functions/open.html][black][b]open[/b][/black][/url][red]([/red]INFILE, [blue]$TheFile[/blue][red])[/red] or [url=http://perldoc.perl.org/functions/die.html][black][b]die[/b][/black][/url] [red]"[/red][purple]The file [blue]$TheFile[/blue] could not be found: [blue]$![/blue][/purple][red]"[/red][red];[/red]
[olive][b]while[/b][/olive] [red]([/red]<INFILE>[red])[/red] [red]{[/red]
   [black][b]my[/b][/black] [blue]$TheLine[/blue] = [blue]$_[/blue][red];[/red]
   [url=http://perldoc.perl.org/functions/chomp.html][black][b]chomp[/b][/black][/url][red]([/red][blue]$TheLine[/blue][red])[/red][red];[/red]
   [olive][b]if[/b][/olive] [red]([/red][red]/[/red][purple](VOLUME GROUP:[purple][b]\s[/b][/purple]+[purple][b]\S[/b][/purple]+)[/purple][red]/[/red][red])[/red] [red]{[/red]
      [url=http://perldoc.perl.org/functions/push.html][black][b]push[/b][/black][/url] [blue]@output[/blue], [blue]$1[/blue][red];[/red]
   [red]}[/red]
   [olive][b]elsif[/b][/olive] [red]([/red][red]/[/red][purple]TOTAL PPs:[purple][b]\s[/b][/purple]+[purple][b]\d[/b][/purple]+[purple][b]\s[/b][/purple]+[purple][b]\([/b][/purple](.*?)[purple][b]\)[/b][/purple][/purple][red]/[/red][red])[/red] [red]{[/red]
      [black][b]push[/b][/black] [blue]@output[/blue],[red]"[/red][purple]TOTAL: [blue]$1[/blue][/purple][red]"[/red][red];[/red]
   [red]}[/red]
   [olive][b]elsif[/b][/olive] [red]([/red][red]/[/red][purple]FREE PPs:[purple][b]\s[/b][/purple]+[purple][b]\d[/b][/purple]+[purple][b]\s[/b][/purple]+[purple][b]\([/b][/purple](.*?)[purple][b]\)[/b][/purple][/purple][red]/[/red][red])[/red] [red]{[/red]
      [black][b]push[/b][/black] [blue]@output[/blue],[red]"[/red][purple]FREE: [blue]$1[/blue][/purple][red]"[/red][red];[/red]
   [red]}[/red]
   [olive][b]elsif[/b][/olive] [red]([/red][red]/[/red][purple]USED PPs:[purple][b]\s[/b][/purple]+[purple][b]\d[/b][/purple]+[purple][b]\s[/b][/purple]+[purple][b]\([/b][/purple](.*?)[purple][b]\)[/b][/purple][/purple][red]/[/red][red])[/red] [red]{[/red]
      [black][b]push[/b][/black] [blue]@output[/blue],[red]"[/red][purple]USED: [blue]$1[/blue][/purple][red]"[/red][red];[/red]
      [olive][b]last[/b][/olive][red];[/red] [gray][i]#<-- stop reading the file this is all we need[/i][/gray]
   [red]}[/red]
[red]}[/red]
[url=http://perldoc.perl.org/functions/close.html][black][b]close[/b][/black][/url][red]([/red]INFILE[red])[/red][red];[/red]
[url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] [red]"[/red][purple][blue]$_[/blue][purple][b]\n[/b][/purple][/purple][red]"[/red] [olive][b]for[/b][/olive] [blue]@output[/blue][red];[/red]
[tt]------------------------------------------------------------
Pragmas (perl 5.8.8) used :
[ul]
[li]strict - Perl pragma to restrict unsafe constructs[/li]
[li]warnings - Perl pragma to control optional warnings[/li]
[/ul]
[/tt]

*** See ishnids code above for what is a better way to parse your file.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Thanks!!! this is exactly what I needed to get started.
 
Here is my take on this.
Thanks to ishnid for showing me __DATA__.
Thanks to wpdavids for grep. I didn't know this was a Perl cmd.
KevinADC why is grep the wrong thing to use here?
Code:
#!/usr/bin/perl -w
use strict;
use warnings;
my $sysout;
while ( <DATA> )  { 
       my $input = $_;
       if ( /(VOLUME GROUP:)/ ) {
            my $label   = $1;    
            my ($data)  = (split(' ',$_))[2];
            $label     .= ' ' x (12 - length($label)); 
            $sysout    .= "$label $data\n";
       }
       if ( /(TOTAL PPs)/ || /(FREE PPs)/ || /(USED PPs)/ ) {  
            my $label       =   $1;   
           ($label)         =   split(' ',$label);     
            $label         .=   ' ' x (12 - length($label));
            my ($megabyte)  =  (split(/\(/,$_))[1];
            $megabyte       =~  s/\D//g;
            $sysout        .=  "$label: $megabyte\n";
       }       
}
print "$sysout\n";

__DATA__
VOLUME GROUP:       datavg                   VG IDENTIFIER:  000d94600000d600000001117031c111
VG STATE:           active                   PP SIZE:        128 megabyte(s)
VG PERMISSION:      read/write               TOTAL PPs:      4789 (612992 megabytes)
MAX LVs:            256                      FREE PPs:       274 (35072 megabytes)
LVs:                20                       USED PPs:       4515 (577920 megabytes)
OPEN LVs:           20                       QUORUM:         6 (Enabled)
TOTAL PVs:          11                       VG DESCRIPTORS: 11
STALE PVs:          0                        STALE PPs:      0
ACTIVE PVs:         11                       AUTO ON:        yes
MAX PPs per VG:     32512
MAX PPs per PV:     1016                     MAX PVs:        32
LTG size (Dynamic): 1024 kilobyte(s)         AUTO SYNC:      no
HOT SPARE:          no                       BB POLICY:      relocatable
 
ejaggers,

you could use grep if you used in conjunction with a bunch of regexps search patterns, but that gets unwiedly pretty fast when your searching for more than a couple of simple things. Plus grep has to search the entire file/list each seperate time it is used. It seems much more efficient and easier to loop through the file once and use a few targeted regexps and get all the results in one pass over the file.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top