X-Git-Url: http://git.shiar.nl/barcat.git/blobdiff_plain/c53a0e13374a11b34c052685fb6711dd1bd7d8f1..9eb6da139e4958a8f31c03e62073f1a0f6e20898:/barcat diff --git a/barcat b/barcat index 0cfdb2d..0f0cfb8 100755 --- a/barcat +++ b/barcat @@ -26,6 +26,7 @@ GetOptions(\%opt, $opt{anchor} = qr/$_/; } or die $@ =~ s/(?:\ at\ \N+)?\Z/ for option $_[0]/r; }, + 'count|c!', 'human-readable|H!', 'sexagesimal!', 'reformat!', @@ -189,7 +190,7 @@ $opt{'value-format'} = $opt{sexagesimal} ? sub { $opt{'value-format'} ||= sub { sprintf '%.8g', $_[0] }; -my (@lines, @values, @order); +my (@lines, @values, @order, %uniq); $SIG{$_} = \&show_stat for $opt{'signal-stat'} || (); $SIG{ALRM} = sub { @@ -205,17 +206,29 @@ if (defined $opt{interval}) { eval { require Tie::Array::Sorted; tie @order, 'Tie::Array::Sorted', sub { $_[1] <=> $_[0] }; - } or warn $@, "Expect slowdown with large datasets!\n"; + } or warn $@, "Expect slowdown with large datasets!\n" + unless $opt{count}; } my $float = qr<[0-9]* [.]? [0-9]+ (?: e[+-]?[0-9]+ )?>; # positive numberish -my $valmatch = qr< $opt{anchor} ( \h* -? $float |) >x; +my $valmatch = qr< $opt{anchor} ( \h* -? $float |) >; while (defined ($_ = $opt{input} ? shift @{ $opt{input} } : readline)) { s/\r?\n\z//; - s/\A\h*// unless $opt{unmodified}; - my $valnum = s/$valmatch/\n/ && $1; - push @values, $valnum; - push @order, $valnum if length $valnum; + my $valnum; + if ($opt{count}) { + ($valnum) = m/$opt{anchor} (\S*)/; + $valnum //= ''; + $uniq{$valnum}++ and next; + push @values, $valnum; + s/\A/\n /; + } + else { + s/\A\h*// unless $opt{unmodified}; + $valnum = s/$valmatch/\n/ && $1; + push @values, $valnum; + push @order, $valnum if length $valnum; + } + if (defined $opt{trim} and defined $valnum) { my $trimpos = abs $opt{trim}; $trimpos -= length $valnum if $opt{unmodified}; @@ -228,6 +241,8 @@ while (defined ($_ = $opt{input} ? shift @{ $opt{input} } : readline)) { } } push @lines, $_; +} +continue { show_lines() if defined $opt{interval} and $opt{interval} < 0 and $. % $opt{interval} == 0; } @@ -247,6 +262,11 @@ state $nr = $opt{hidemin} ? $opt{hidemin}->($#lines) : 0; my $limit = $opt{hidemax} ? $opt{hidemax}->($#lines, $nr) : $#lines; +if ($opt{count}) { + $_ = $uniq{$_} for @values[$nr .. $limit]; + @order = @values; +} + @order = sort { $b <=> $a } @order unless tied @order; my $maxval = $opt{maxval} // ( $opt{hidemax} ? max grep { length } @values[$nr .. $limit] : @@ -374,6 +394,7 @@ continue { $nr++; } say $opt{palette} ? color(0) : '' if $opt{spark}; +%uniq = () if $opt{interval} and $opt{count}; return $nr; } @@ -438,6 +459,8 @@ Usage: /\_/\ Options: -a, --[no-]ascii Restrict user interface to ASCII characters -C, --[no-]color Force colored output of values and bar markers + -c, --count Omit repetitions and count the number of + occurrences -f, --field=([+]N|REGEXP) Compare values after a given number of whitespace separators @@ -509,6 +532,12 @@ disabled otherwise such as when piped or redirected. Can also be disabled by setting B<-M> or the I environment variable. +=item B<-c>, B<--count> + +Omit repetitions and count the number of occurrences. +Similar to piping input to C +but keeping the order of first appearances. + =item B<-f>, B<--field>=([B<+>]I | I) Compare values after a given number of whitespace separators, @@ -742,19 +771,19 @@ Monitor network latency from prefixed results: ping google.com | barcat -f'time=\K' -t -Commonly used after counting, for example users on the current server: - - users | tr ' ' '\n' | sort | uniq -c | barcat - -Letter frequencies in text files: +Commonly used after counting, eg letter frequencies in text files: cat /usr/share/games/fortunes/*.u8 | perl -CS -nE 'say for grep length, split /\PL*/, uc' | sort | uniq -c | barcat +Users on the current server while preserving order: + + users | tr ' ' '\n' | barcat -c + Number of HTTP requests per day: - cat httpd/access.log | cut -d\ -f4 | cut -d: -f1 | uniq -c | barcat + barcat -cf'\[([^:]+)' httpd/access.log Any kind of database query results, preserving returned alignment: