| Revision 76 (by dpavlin, 2008/04/08 21:05:42) |
added -h to produce human-readable output
|
#!/usr/bin/perl -w
use strict;
use Term::ReadKey qw(GetTerminalSize);
use Getopt::Long;
my $human = 0;
GetOptions(
'human!' => \$human,
);
my @lines;
my $max_size = 0;
my $max_sum = 0;
my $rest_len = 0;
my $sum = 0;
my @units = qw/b k M G/;
sub unit {
my $v = shift;
return $v unless $human;
my $o = 0;
while ( ( $v / 10000 ) >= 1 ) {
$o++;
$v /= 1024;
}
if ( $v >= 1 ) {
return sprintf("%d%s", $v, $units[$o]);
} elsif ( $v == 0 ) {
return 0;
} else {
return sprintf("%.1f%s", $v, $units[$o]);
}
}
while(<>) {
chomp;
if (/\s*([\d\.]+)\s+(.+)/) {
my ($size,$rest) = ($1,$2);
$sum += $size;
$max_size = $size if ($size > $max_size);
$max_sum = $sum if ($sum > $max_sum);
my $rl = length($rest);
$rest_len = $rl if ($rl > $rest_len);
push @lines, [ $size, $rest, $sum ];
} else {
print STDERR "# $_\n";
}
}
my $cols = eval { (Term::ReadKey::GetTerminalSize)[0] } || $ENV{COLS} || $ENV{COLUMNS} || 80;
# convert to chars
my $size_len = length($max_size);
my $sum_len = length($max_sum);
my $bar_size = $cols - $rest_len - $sum_len - $size_len - 4;
sub bar_size {
my ($v,$m) = @_;
return int($v * $bar_size / $m)
}
sub bar {
my ($v1,$m1,$v2,$m2) = @_;
my $b1 = bar_size($v1, $m1);
my $b2 = bar_size($v2, $m2);
my $bar = '';
if ($b1 < $b2) {
$bar .= "O" x $b1;
$bar .= "-" x ($b2 - $b1);
} elsif ($b1 > $b2) {
$bar .= "*" x $b2;
$bar .= "-" x ($b1 - $b2);
} else {
$bar .= "O" x $b1;
}
}
foreach my $l (@lines) {
my ($size,$r,$tmpsum) = @{$l};
# printf "%-50s\t[ + %-8d= %-8d ]\n",$r,$size,$tmpsum;
printf "%-${rest_len}s %${size_len}s %-${bar_size}s %${sum_len}s\n",
$r, unit($size), bar($size, $sum, $tmpsum, $sum), unit($tmpsum);
}