Hi Rob,
Thanks for your response and to everyone else who had given their thoughts,
especially John. This whole exercise is turning out to be a "fun" way of
learning arrays and print formatting.
I tried the script that you suggested and it is giving some error and not
sure how to get around it. FYI, I commented out use strict and use warnings
for the time being 'coz it gives error as below:
Use of implicit split to @_ is deprecated at ./df.pl line 30.
Bareword "MBytes" not allowed while "strict subs" in use at ./df.pl line 32.
Bareword "GBytes" not allowed while "strict subs" in use at ./df.pl line 33.
Execution of ./df.pl aborted due to compilation errors.
I then run the script and it gives error as below:
Can't locate object method "rec" via package "Filesystem" (perhaps you
forgot to load "Filesystem"?) at ./df.pl line 30.
Does it matter that the df -k header is not Filesystem KBytes Used Avail
Capacity Mount?
For Solaris, the header is
Filesystem kbytes used avail capacity Mounted on
For Linux, the header is
Filesystem 1K-blocks Used Available Use% Mounted on
Note that the Filesystem KBytes Used Avail Capacity Mount is a
pre-formatted header in the UNIX shell version of the script. Also, the df
-k output for example on a Linux system will sometimes flow over one (1)
line, example below. FYI, if re-directed to a file, all output line are
one-liner, if re-directed to STDOUT, output is as shown below. Perhaps the my
@data = `df -k`; line is giving the same output when df is not re-directed
to a file. Will check that out.
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/vg0-lv1 16251816 3067896 12345060 20% /
/dev/mapper/vg0-lv2 8125880 3265032 4441420 43% /home
/dev/mapper/vg0-lv3 2031440 73672 1852912 4% /tmp
/dev/mapper/vg0-lv4 4062912 642436 3210764 17% /var
/dev/mapper/vg0-lv5 1015704 34104 929172 4% /var/tmp
/dev/mapper/vg0-lv6 73133256 46655684 22702700 68% /u01
/dev/sda1 101086 28173 67694 30% /boot
tmpfs 49422824 237564 49185260 1% /dev/shm
dev0ns100:/vol/vol_ns953_snap/rac_shared
125829120 32990784 92838336 27% /nas_mnt/rac_shared
/dev/asm/akl1od200-335
786432000 312987896 473444104 40% /asm
The script is as below:
#!/usr/bin/perl
#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);
}
my @data = `df -k`;
# Drop the header line and sort the data lines
#
shift @data;
@data = sort @data;
# Parse each data record into a hash.
# Convert the KBytes field to new MBytes and GBytes fields.
# Do the same in-place for Used and Avail.
# And replace the data line with a referece to the new hash
#
foreach (@data) {
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/;
$_ = \%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);
}
On Tue, Oct 25, 2011 at 9:04 PM, Rob Dixon <[email protected]> wrote:
> On 24/10/2011 21:35, John W. Krahn wrote:
> >
> > You forgot the part where the OP wants to sort the output. :-)
>
> I thought I didn't have enough information to know how the OP wanted the
> report sorted, but I see from the attacked shell script that the
> original lines from the df output are sorted before reformatting. To
> achieve that the complete df listing must be in memory, so it is simpler
> to use backticks rather than opening a pipe.
>
> The fix below replaces the original code from
>
> # Open a pipe from the df command
>
> to the end of the while loop. The rest of the program stays the same.
>
> Cheers,
>
> Rob
>
>
> my @data = `df -k`;
>
> # Drop the header line and sort the data lines
> #
> shift @data;
> @data = sort @data;
>
> # Parse each data record into a hash.
> # Convert the KBytes field to new MBytes and GBytes fields.
> # Do the same in-place for Used and Avail.
> # And replace the data line with a referece to the new hash
> #
> foreach (@data) {
>
> 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/;
>
> $_ = \%rec;
> }
>
> **OUTPUT**
>
> Filesystem MBytes Used Avail
> Capacity Mount
> -------------------------------------- --------- --------- --------
> -------- -----------------
> /dev/md/dsk/d1 3027-MB 2424-MB 542-MB
> 82% /
> /dev/md/dsk/d3 3027-MB 1558-MB 1408-MB
> 53% /var
> /dev/md/dsk/d4 4886-MB 4229-MB 608-MB
> 88% /opt
> /proc 0-MB 0-MB 0-MB
> 0% /proc
> dev0ns951:/vol/vol_admin/admin 38810-MB 32189-MB 6621-MB
> 83% /nas_mnt/admin
> dev0ns951:/vol/vol_admin/admin/cpadocs 38810-MB 32189-MB 6621-MB
> 83% /opt/info
> dev0ns951:/vol/vol_admin/common 314368-MB 260633-MB 53735-MB
> 83% /nas_mnt/common
> 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% /home/users
> 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
> fd 0-MB 0-MB 0-MB
> 0% /dev/fd
> mnttab 0-MB 0-MB 0-MB
> 0% /etc/mnttab
> swap 8460-MB 0-MB 8460-MB
> 1% /var/run
> swap 8513-MB 54-MB 8460-MB
> 1% /tmp
>
> --
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
> http://learn.perl.org/
>
>
>