X-Git-Url: http://git.shiar.nl/barcat.git/blobdiff_plain/8ad843b82944ba03a821aafd4ca738a379cd4206..cdad4c9fc575cb94974ae27e451aed47fc072710:/barcat diff --git a/barcat b/barcat index 785df75..4c3cf8a 100755 --- a/barcat +++ b/barcat @@ -6,7 +6,7 @@ use List::Util qw( min max sum ); use open qw( :std :utf8 ); use experimental qw( lexical_subs ); -our $VERSION = '1.03'; +our $VERSION = '1.04'; use Getopt::Long '2.33', qw( :config gnu_getopt ); sub podexit { @@ -61,6 +61,8 @@ $opt{units} = [split //, ' kMGTPEZYyzafpnμm'] if $opt{'human-readable'}; $opt{anchor} //= qr/\A/; $opt{'value-length'} = 6 if $opt{units}; +my (@lines, @values, @order); + if (defined $opt{interval}) { $opt{interval} ||= 1; $SIG{ALRM} = sub { @@ -68,16 +70,21 @@ if (defined $opt{interval}) { alarm $opt{interval}; }; alarm $opt{interval}; + + eval { + require Tie::Array::Sorted; + tie @order, 'Tie::Array::Sorted', sub { $_[1] <=> $_[0] }; + } or warn $@, "Expect slowdown with large datasets!\n"; } $SIG{INT} = 'IGNORE'; # continue after assumed eof -my (@lines, @values); my $valmatch = qr/$opt{anchor} ( \h* -? [0-9]* \.? [0-9]+ (?: e[+-]?[0-9]+ )? |)/x; while (readline) { s/\r?\n\z//; s/^\h*// unless $opt{unmodified}; push @values, s/$valmatch/\n/ && $1; + push @order, $1 if length $1; if (defined $opt{trim}) { my $trimpos = abs $opt{trim}; if ($trimpos <= 1) { @@ -92,8 +99,6 @@ while (readline) { $SIG{INT} = 'DEFAULT'; -my @order; - sub show_lines { state $nr = $opt{hidemin} ? $opt{hidemin} - 1 : 0; @@ -101,9 +106,9 @@ state $nr = $opt{hidemin} ? $opt{hidemin} - 1 : 0; @lines or return; @lines > $nr or return unless $opt{hidemin}; -@order = sort { $b <=> $a } grep { length } @values; -my $maxval = $opt{hidemax} ? max @values[0 .. $opt{hidemax} - 1] : $order[0]; -my $minval = min $order[-1], 0; +@order = sort { $b <=> $a } @order unless tied @order; +my $maxval = ($opt{hidemax} ? max grep { length } @values[0 .. $opt{hidemax} - 1] : $order[0]) // 0; +my $minval = min $order[-1] // (), 0; my $lenval = $opt{'value-length'} // max map { length } @order; my $len = defined $opt{trim} && $opt{trim} <= 0 ? -$opt{trim} + 1 : max map { length $values[$_] && length $lines[$_] } @@ -171,6 +176,11 @@ while ($nr <= $#lines) { show_lines(); if ($opt{stat}) { + if ($opt{hidemin} or $opt{hidemax}) { + $opt{hidemin} ||= 1; + $opt{hidemax} ||= @lines; + printf '%s of ', sum(@values[$opt{hidemin} - 1 .. $opt{hidemax} - 1]) // 0; + } my $total = sum @order; printf '%s total', $total; printf ' in %d values', scalar @values;