'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"
);
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;
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;
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.