On 22/10/2011 03:18, newbie01 perl wrote:
> Hi all,
> 
> Am trying to write/convert a customized df script in Perl and need some 
> help with regards to using arrays and file handlers.
> 
> At the moment am using
> 
> system("df -k > /tmp/df_tmp.00");
> 
> To re-direct the df output. Am using df -k because some of the Solaris 
> and HP servers does not have df -h, by using df -k, am sure it will work 
> on all of them.

[snip]

> 
> Then I get rid of the header as below, more dependence on using Unix OS 
> commands, sorry Perl gurus, don't know what's the equivalent of the 
> commands below in Perl :-)
> 
> $num_lines=`wc -l /tmp/df_${processid}.00 | awk '{ print \$1 }'`;
> $num_lines=$num_lines-1;
> system("tail -${num_lines} /tmp/df_tmp.00 > /tmp/df_tmp.01");
> 
> Then I do the lines below which read each line to an array:
> 
> open(DFTMP, "/tmp/df_tmp.01");
> while ( <DFTMP> )
> {
>     chomp;
>     @df_lines= split(' ',$_);
> }
> close DFTMP;
> 
> My question is, first of all, how to do an array operation where I can 
> operate on the field/column 2,3,4 where I can divide them by 1024 or 
> 1024/1024 so their KB values are converted to MB or GB? Or do I have to 
> foreach each array member and do the division line by line? Would be 
> nice if I can use the df header as hash references :-)
> 
> Also need to be able to get the max(length) of each column so I can use 
> it for formatting the output and I can't find a Perl max or min function :(-
> 
> BTW, if anyone is interested to know what am trying to do, I've attached 
> a version of the script in Korn shell.
> 
> Am wanting to convert it to Perl 'coz I have a server that has 30+ lines 
> of df output and it takes ages to run using Korn shell. I am hoping that 
> it will run faster in Perl, John W. Krahn had proven that to be case 
> lots of times, thanks John :-)
> 
> Plus it is a good exercise to learn Perl arrays and sorting too.
> 
> Any advise/feedback much appreciated. Thanks in advance.

The program below seems to do the job.

Hope it helps,

Rob


use strict;
use warnings;

use List::Util qw/max/;

sub kb_to_mb {
  sprintf "%.0f-MB", shift(@_) / 1024;
}

sub kb_to_gb {
  sprintf "%.0f-GB", shift(@_) / (1024 * 1024);
}

# Open a pipe from the df command
#
open my $df, '-|', 'df -k' or die $!;

<$df>; # Drop the header line

# Parse each data record into a hash.
# Convert the KBytes field to new MBytes GBytes fields.
# Do the same in-place for Used and Avail.
# And push it onto the @data array.
#
my @data;

while (<$df>) {

  my %rec;
  @rec{qw/Filesystem KBytes Used Avail Capacity Mount/} = split;

  $rec{MBytes} = kb_to_mb $rec{KBytes};
  $rec{GBytes} = kb_to_gb $rec{KBytes};
  $rec{$_} = kb_to_mb $rec{$_} for qw/Used Avail/;
  
  push @data, \%rec;
}

# Build a %width hash with column names for keys and maximum field width for 
values.
# Include the column names themselves in the list, in case header is longer 
than all data.
# Negate Filesystem and Mount widths to left-justify them.
# 
my %width;
foreach my $key (keys %{$data[0]}) {
  $width{$key} = max map length, ($key, map $_->{$key}, @data);
}
$width{Filesystem} = -$width{Filesystem};
$width{Mount} = -$width{Mount};

# Set the list of columns to be displayed.
# Build a format string consisting of sufficient %*s format specifications, 
separated by spaces.
#
my @columns = qw/Filesystem MBytes Used Avail Capacity Mount/;
my $format = join(' ', ('%*s') x @columns)."\n";

# Print the column headers
#
printf $format, map(($width{$_}, $_), @columns);

# Print matching rows of hyphens
#
printf $format, map(($width{$_}, '-' x abs $width{$_}), @columns);

# Print each row of data
#
foreach my $rec (@data) {
  printf $format, map(($width{$_}, $rec->{$_}), @columns);
}

__END__

**OUTPUT**

Filesystem                                MBytes      Used    Avail Capacity 
Mount            
-------------------------------------- --------- --------- -------- -------- 
-----------------
/dev/md/dsk/d1                           3027-MB   2424-MB   542-MB      82% /  
              
/proc                                       0-MB      0-MB     0-MB       0% 
/proc            
mnttab                                      0-MB      0-MB     0-MB       0% 
/etc/mnttab      
fd                                          0-MB      0-MB     0-MB       0% 
/dev/fd          
/dev/md/dsk/d3                           3027-MB   1558-MB  1408-MB      53% 
/var             
swap                                     8460-MB      0-MB  8460-MB       1% 
/var/run         
swap                                     8513-MB     54-MB  8460-MB       1% 
/tmp             
/dev/md/dsk/d4                           4886-MB   4229-MB   608-MB      88% 
/opt             
dev0ns951:/vol/vol_admin/common        314368-MB 260633-MB 53735-MB      83% 
/nas_mnt/common  
dev0ns951:/vol/vol_admin/admin/cpadocs  38810-MB  32189-MB  6621-MB      83% 
/opt/info        
dev0ns951:/vol/vol_admin/admin          38810-MB  32189-MB  6621-MB      83% 
/nas_mnt/admin   
dev0ns951:/vol/vol_admin/docs            8270-MB   7076-MB  1194-MB      86% 
/nas_mnt/docs    
dev0ns951:/vol/vol_admin/prodhome       32870-MB  25964-MB  6906-MB      79% 
/nas_mnt/prodhome
dev0ns951:/vol/vol_admin/saphome           90-MB     37-MB    53-MB      42% 
/nas_mnt/saphome 
dev0ns951:/vol/vol_admin/prodhome       32870-MB  25964-MB  6906-MB      79% 
/home/users      

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to