negative limit counts from last line
authorMischa POSLAWSKY <perl@shiar.org>
Sat, 27 Mar 2021 22:57:35 +0000 (23:57 +0100)
committerMischa POSLAWSKY <perl@shiar.org>
Mon, 31 Oct 2022 22:42:56 +0000 (23:42 +0100)
barcat
t/t1504-bottom_limit_-L-3.out [moved from t/t1504-bottom_limit_-L-3_#TODO.out with 100% similarity]

diff --git a/barcat b/barcat
index 82f0fffd51870985cf19a30503e9e4dcb24535f6..5d0f85c287b571a726a6426ae027406b3b8cb0ef 100755 (executable)
--- a/barcat
+++ b/barcat
@@ -39,8 +39,9 @@ GetOptions(\%opt,
        'limit|L:s' => sub {
                my ($optname, $optval) = @_;
                $optval ||= 0;
+               $optval =~ /\A-[0-9]+\z/ and $optval .= '-';  # tail shorthand
                ($opt{hidemin}, $opt{hidemax}) =
-               $optval =~ m/\A (?: ([0-9]+)? - )? ([0-9]+)? \z/ or die(
+               $optval =~ m/\A (?: (-? [0-9]+)? - )? ([0-9]+)? \z/ or die(
                        "Value \"$optval\" invalid for option limit",
                        " (range expected)\n"
                );
@@ -205,7 +206,9 @@ sub color {
 
 sub show_lines {
 
-state $nr = $opt{hidemin};
+state $nr =
+       $opt{hidemin} < 0 ? @lines + $opt{hidemin} + 1 :
+       $opt{hidemin};
 @lines or return;
 @lines > $nr or return;
 
@@ -316,9 +319,12 @@ say $opt{palette} ? color(0) : '' if $opt{spark};
 
 sub show_stat {
        if ($opt{hidemin} or $opt{hidemax}) {
-               printf '%.8g of ', $opt{'sum-format'}->(sum(grep { length }
-                       @values[$opt{hidemin} .. ($opt{hidemax} || @lines) - 1]
-               ) // 0);
+               my $linemin = $opt{hidemin};
+               $linemin += @lines if $linemin < 0;
+               my $linemax = ($opt{hidemax} || @lines) - 1;
+               printf '%.8g of ', $opt{'sum-format'}->(
+                       sum(grep {length} @values[$linemin .. $linemax]) // 0
+               );
        }
        if (@order) {
                my $total = sum @order;
@@ -422,9 +428,13 @@ unless C<--length=0>.
 Prepend a dash (i.e. make negative) to enforce padding
 regardless of encountered contents.
 
-=item -L, --limit[=(<count> | <start>-[<end>])]
+=item -L, --limit[=(<count> | -<last> | <start>-[<end>])]
 
 Stop output after a number of lines.
+A single value indicates the last line number (like C<head>),
+or first line counting from the bottom if negative (like C<tail>).
+A specific range can be given by two values.
+
 All input is still counted and analyzed for statistics,
 but disregarded for padding and bar size.