#!/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); }