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: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/