Created
February 28, 2023 23:12
-
-
Save briandfoy/5c89c40bedc818ee74845a0204ce20e0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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<< <[email protected]> >> | |
=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