#!/usr/bin/perl
#
# FileSizeHist [-s] [-u<n>] [file]...
#
# This takes a list of file names on the command line or in stdin, and
# produces  a histogram of the file counts and sizes.  The result is a
# graph that looks like:

#                1         2         3         4         5
#      X xxxxXxxxxXxxxxXxxxxXxxxxXxxxxXxxxxXxxxxXxxxxXxxxxXxxxxX
# (1k)   XXXxxxxxxxxxxxx
# (2k)   XXxxxxxxx
# (3k)   Xxxx
# (4k)   XXxxxxxxxxxx
# (5k) x XXxxxxxxxxxxxx
# (6k)   Xxxxxxx

# and so on.  The vertical scale is sizes in Kbytes; each  line  shows
# the  count and space taken up by files of that size.  The horizontal
# scale combines two figures: The file counts (X) and total space (x).
# The  first  line  showing  the horizontal scale.  The use of X and x
# makes the graph look nice when displayed  with  xterms  "unreadable"
# 1x2  font.   If the -u<n> option is present, it gives the horizontal
# scale unit (in bytes); the default is 1000.

for $f (@ARGV) {
	if ($f =~ /^-[Ss](\d*)$/) {
		$sleep = $1 || 1000000;
	} elsif ($f =~ /^-[Uu](\d+)$/) {
		$u = $1;	# Unit.
	} else {
		&fname($f);
		++$files;
	}
}
if (!$files) {
	for $f (<STDIN>) {
		$f =~ s/^\s+//;
		$f =~ s/\s+$//;
		&fname($f);
	++$files;
	}
}
print "* xxxxXxxxxXxxxxXxxxxXxxxxXxxxxXxxxxXxxxxXxxxxXxxxxXxxxxX\n";
for ($k = 0; $k <= $max; $k++) {
		print(($k % 5) ? '  ' : ($k % 10) ? 'x ' : 'X ');
	if ($c = $cnt[$k]) {
		for ($n = 0; $n < $c; $n++) {
			print 'X';
		}
		for ($s = $n * $u; $s < $siz[$k]; $s += $u) {
			print 'x';
		}
		print "\n";
	} else {
		print "  \n";
	}
}
sleep $sleep if ($sleep);
exit 0;

sub fname {
	local($f) = @_;
#	local($n,$k,$s,@s);
	if (@s = stat($f)) {
		$n = $s[7];	# Get its size.
		$k = int($n / 1000);
		$siz[$k] += $n;
		$cnt[$k] += 1;
		$max = $k if $max < $k;
	}
}
