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/