4 use List::Util qw( max sum );
5 use open qw( :std :utf8 );
9 use Getopt::Long '2.33';
10 sub podexit { require Pod::Usage; Pod::Usage::pod2usage(-exitval => 0, @_) }
14 'usage|h' => sub { podexit() },
15 'help' => sub { podexit(-verbose => 2) },
16 ) or exit 64; # EX_USAGE
17 $opt{width} ||= $ENV{COLUMNS} || 80;
20 my @lines = readline or exit;
22 my @values = map { s/^\h* ( -? [0-9]* (?:\.[0-9]+)? )//x and $1 } @lines;
23 my @order = sort { $b <=> $a } grep { length } @values;
24 my $maxval = $order[0];
25 my $minval = min $order[-1], 0;
27 my $lenval = max map { length } @order;
28 my $len = 1 + max map { length } @lines; # left padding
29 my $size = ($maxval - $minval) &&
30 ($opt{width} - $lenval - $len) / ($maxval - $minval); # bar multiplication
32 sub orderpos { (($order[$_[0]] + $order[$_[0] + .5]) / 2 - $minval) * $size }
34 $barmark[ (sum(@order) / @order - $minval) * $size ] = '='; # average
35 $barmark[ orderpos($#order / 2) ] = '+'; # mean
36 $barmark[ -$minval * $size ] = '|' if $minval < 0; # zero
37 defined and $opt{color} and $_ = "\e[36m$_\e[0m" for @barmark;
39 for my $nr (0 .. $#lines) {
40 my $val = $values[$nr];
42 my $color = !$opt{color} ? 0 :
43 $val == $order[0] ? 32 : # max
44 $val == $order[-1] ? 31 : # min
46 printf "\e[%sm", $color if $color;
47 printf "%*s", $lenval, $val;
48 print "\e[0m" if $color;
50 printf '%-*s', $len, $lines[$nr];
51 print $barmark[$_] // '-' for 1 .. (($val || 0) - $minval) * $size;
59 graph - append bar chart to input numbers
63 B<graph> [<options>] [<input>]
67 Each line starting with a number is given a bar to visualise relative sizes.
75 Disable colored output of values and bar markers.
77 =item -w, --width=<columns>
79 Override the maximum number of columns to use.
80 Appended graphics will extend to fill up the entire screen.
86 Commonly used after counting, such as users on the current server:
88 users | sed 's/ /\n/g' | sort | uniq -c | graph
90 Letter frequencies in text files:
92 cat /usr/share/games/fortunes/*.u8 |
93 perl -CO -nE 'say for grep length, split /\PL*/, uc' |
94 sort | uniq -c | graph
96 Memory usage of user processes:
98 ps xo %mem,pid,cmd | graph -l40
100 Sizes (in megabytes) of all root files and directories:
104 Number of HTTP requests per day:
106 cat log/access.log | cut -d\ -f4 | cut -d: -f1 | uniq -c | graph
108 Any kind of database query with leading counts:
110 echo 'SELECT count(*),schemaname FROM pg_tables GROUP BY 2' |
113 Git statistics, such commit count by year:
115 git log --pretty=%ci | cut -b-4 | uniq -c | graph
117 Or the most frequent authors:
119 git shortlog -sn | graph | head -3
123 Mischa POSLAWSKY <perl@shiar.org>