Skip to content

Instantly share code, notes, and snippets.

@briandfoy
Created February 28, 2023 23:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save briandfoy/5c89c40bedc818ee74845a0204ce20e0 to your computer and use it in GitHub Desktop.
Save briandfoy/5c89c40bedc818ee74845a0204ce20e0 to your computer and use it in GitHub Desktop.
#!/Users/brian/bin/perl
use v5.36;
use open qw(:std :utf8);
use utf8;
use File::Basename;
use Text::Shellwords qw(shellwords);
=head1 NAME
history_counter.pl - count the commands I use in my shell
=head1 SYNOPSIS
% history | perl history_counter.pl
212 perl
210 git
175 cd
159 ls
82 make
=head1 DESCRIPTION
This program counts the number of times I've used a particular command
in my shell history. It's smart enough to recognize multiple commands on
one line if I used pipelines or compound commands (C<&&>, C<||>, and C<;>).
This works with B<bash> and B<zsh>, which assume that a line from B<history>
has a command number and then the command:
% history
3024 history | perl -F'\s+' -le 'print $F[2]' | sort | uniq -c | sort -nr | head -5
3025 history | perl history.pl | head -5
3026 zsh
3027 history
=head1 AUTHOR
brian d foy, C<< <briandfoy@pobox.com> >>
=head1 COPYRIGHT & LICENSE
This program is available under the Artistic License 2.0,
L<https://opensource.org/license/artistic-license-2-0-php/>
=cut
my %Commands;
LINE: while( <> ) {
chomp;
my @words = shellwords $_;
# get rid of the line number
shift @words;
# some command lines are invalid, like unbalanced quotes
# In that case, shellwords returns a single element.
next LINE unless @words;
my @line_commands = [];
TOKEN: while( my $token = shift @words ) {
state %command_separators = map { $_ => 1 } qw( || && | ; );
if( exists $command_separators{$token} ) {
push @line_commands, [];
next TOKEN;
}
push $line_commands[-1]->@*, $token;
}
my @bins = map { $_->[0] } @line_commands;
foreach my $bin ( @bins ) { $Commands{$bin}++ }
}
foreach my $bin ( sort { $Commands{$b} <=> $Commands{$a} } keys %Commands ) {
printf "%4d %s\n", $Commands{$bin}, $bin;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment