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]*)// and $1 } @lines;
23 my @order = sort { $b <=> $a } @values;
24 my $maxval = max $order[0], -$order[-1];
25 my $lenval = 1 + ($order[-1] < 0) + int log($maxval || 1) / log 10; # max string length
26 my $len = 1 + max map { length } @lines; # left padding
27 my $size = ($opt{width} - $lenval - $len) / $maxval; # bar multiplication
29 sub orderpos { ($order[$_[0]] + $order[$_[0] + .5]) / 2 * $size }
31 $barmark[ sum(@values) / @values * $size ] = '='; # average
32 $barmark[ orderpos($#order / 2) ] = '+'; # mean
33 defined and $opt{color} and $_ = "\e[36m$_\e[0m" for @barmark;
35 for my $nr (0 .. $#lines) {
36 my $val = $values[$nr];
37 my $color = !$opt{color} ? 0 :
38 $val == $order[0] ? 32 : # max
39 $val == $order[-1] ? 31 : # min
41 printf "\e[%sm", $color if $color;
42 printf "%*s", $lenval, $val;
43 print "\e[0m" if $color;
44 printf '%-*s', $len, $lines[$nr];
45 print $barmark[$_] // '-' for 1 .. abs $val * $size;
53 graph - append bar chart to input numbers
57 B<graph> [<options>] [<input>]
61 Each line starting with a number is given a bar to visualise relative sizes.
69 Disable colored output of values and bar markers.
71 =item -w, --width=<columns>
73 Override the maximum number of columns to use.
74 Appended graphics will extend to fill up the entire screen.
80 Commonly used after counting, such as users on the current server:
82 users | sed 's/ /\n/g' | sort | uniq -c | graph
84 Letter frequencies in text files:
86 cat /usr/share/games/fortunes/*.u8 |
87 perl -CO -nE 'say for grep length, split /\PL*/, uc' |
88 sort | uniq -c | graph
90 Memory usage of user processes:
92 ps xo %mem,pid,cmd | graph -l40
94 Sizes (in megabytes) of all root files and directories:
98 Number of HTTP requests per day:
100 cat log/access.log | cut -d\ -f4 | cut -d: -f1 | uniq -c | graph
102 Any kind of database query with leading counts:
104 echo 'SELECT count(*),schemaname FROM pg_tables GROUP BY 2' |
107 Git statistics, such commit count by year:
109 git log --pretty=%ci | cut -b-4 | uniq -c | graph
111 Or the most frequent authors:
113 git shortlog -sn | graph | head -3
117 Mischa POSLAWSKY <perl@shiar.org>