App-freqtable

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

0.010   2025-08-03  Released-By: PERLANCAR; Backward-Incompatible: yes; Urgency: medium

        [NEW FEATURES]

        - Add option --format for custom formatting.

        - The --percent option can noew be specified more than once to display
          frequency as integers as well as percentages.

        [INCOMPATIBLE CHANGES]

        - Replace --freq with --rank (-r).


0.009   2025-07-24  Released-By: PERLANCAR; Urgency: medium

        - Add options: --print-total (-t), --no-print-total (-T),
          --clear-before-output, --output-every.

        - [bugfix] Fix percent formatting.


0.008   2023-12-28  Released-By: PERLANCAR; Urgency: medium

        - Add option: --percent (-p).


0.007   2022-05-20  Released-By: PERLANCAR; Urgency: medium

        - [ux] Add -a as shortcut for --sort=asciibetically.

        - [doc] Forgot to document --sort-sub, --sort-arg, and -a.


0.006   2022-05-20  Released-By: PERLANCAR; Urgency: medium

script/freqtable  view on Meta::CPAN

my %Opts = (
    mode => 'line',
    ignore_case => 0,
    print_total => 0,
    print_freq => 1,
    # XXX options to limit memory usage, e.g. max keys, max line length, --md5 (like in nauniq), ...
    min_rank => undef,
    max_rank => undef,
    sort_args => {},
    sort_sub => undef,
    percent => 0,
    clear_before_output => 0,
    output_every => undef,
    format => undef,
);
my $Numeric;
my %Occurences;

sub parse_cmdline {
    my $res = GetOptions(
        'bytes|c'   => sub { $Opts{mode} = 'byte' },

script/freqtable  view on Meta::CPAN

        'integer|i' => sub { $Opts{mode} = 'integer' },
        'ignore-case|f' => \$Opts{ignore_case},
        'no-print-freq|F' => sub { $Opts{print_freq} = 0 },
        'print-freq'      => sub { $Opts{print_freq} = 1 },
        'no-print-total|T' => sub { $Opts{print_total} = 0 },
        'print-total|t'    => sub { $Opts{print_total} = 1 },
        'rank|r=s' => \$tmp_rank,
        'sort-sub=s' => \$Opts{sort_sub},
        'sort-arg=s%' => $Opts{sort_args},
        'a'   => sub { $Opts{sort_sub} = 'asciibetically' },
        'percent|p' => sub { $Opts{percent}++ },
        'clear-before-output' => sub { $Opts{clear_before_output} = 1 },
        'output-every=i' => \$Opts{output_every},
        'format=s' =>\$Opts{format},
        'help|h'  => sub {
            print <<USAGE;
Usage:
  freqtable [OPTIONS]... < INPUT
  freqtable --help (or -h)
Options:
  --bytes, -c
  --chars, -m
  --words, -w
  --lines, -l
  --number, -n
  --integer, -i
  --ignore-case, -f
  --print-freq
  --no-print-freq, -F
  --print-total, -t
  --no-print-total, -T
  --percent, -p
  --format=FMT
  --rank N|M-N|M-|-N, -r
  --sort-sub=SPEC
  --sort-arg=ARG=VAL
  -a
  --output-every=i
  --clear-before-output
For more details, see the manpage/documentation.
USAGE
            exit 0;

script/freqtable  view on Meta::CPAN


    if (defined $Opts{format}) {
        my $pct = $totoccurrences == 0 ? 0 : $n/$totoccurrences*100;
        {
            no warnings; # XXX only disable warning 'redundant argument in printf'
            printf $Opts{format}, $n, $k, $pct;
            print "\n";
        }
    } else {
        if ($Opts{print_freq}) {
            unless ($Opts{percent} && $Opts{percent} < 2) {
                printf "%9d ", $n;
            }
            if ($Opts{percent}) {
                my $pct = $totoccurrences == 0 ? 0 : $n/$totoccurrences*100;
                printf "%6.2f%% ", $pct;
            }
        }
        print $k, "\n";
    }
}

sub _display_table {
    my @keys = keys %Occurences;

script/freqtable  view on Meta::CPAN

 five
 eight
 one
 four
 nine
 seven
 six
 three
 two

=head2 Formatting the output line: showing the percentages (`--percent`, `-p` option)

The default is to show frequencies as numbers:

 % freqtable input-lines.txt
         3 five
 ...

You can display frequencies as percent instead:

 % freqtable -p input-lines.txt
  23.08% five
 ...

Specify another `-p` if you want to display frequencies as integers as well as
percent:

 % freqtable -pp input-lines.txt
         3  23.08% five
 ...

=head2 Formatting the output line: custom formatting (`--format` option)

 % freqtable --format '%04d: %s' input-lines.txt
 0003: five

script/freqtable  view on Meta::CPAN

=head2 Running table (`--output-every` option)

If you have streaming input, you can instruct `freqtable` to print the result
periodically after a number of input lines/words/characters/bytes. You can also
instruct to clear the terminal screen before every output
(`--clear-before-output`).

 % perl -MArray::Sample::WeightedRandom=sample_weighted_random_with_replacement \
     -E'say sample_weighted_random_with_replacement(
          [ ["a", 1], ["b", 2], ["c", 3], ["d",5] ], 1) while 1' | \
   freqtable --output-every 10000 --clear --percent

Sample output:

 45.43%  d
 27.28%  c
 18.20%  b
  9.10%  a

=head1 DESCRIPTION

script/freqtable  view on Meta::CPAN


=item * --sort-arg=ARGNAME=ARGVALUE

Pass argument(s) to the sort subroutine. Can be specified multiple times, once
for every argument.

=item * -a

Shortcut for C<--sort=asciibetically>.

=item * --percent, -p

Show frequencies as percentages instead of integers. If you specify this option
one more time, will show frequencies as integers I<as well as> percentages.

=item * --format=s

Format frequency line using `sprintf()` template. `freqtable` will supply these
arguments after the template: frequency integer, item string, and frequency as
percent. For example:

 %04d: %s              # sample output: 0004: five

If you want to display the item first, you can use something like:

 %2$-12s: %d
 # sample output:
 five        : 3
 eight       : 2



( run in 1.665 second using v1.01-cache-2.11-cpan-39bf76dae61 )