Search for…​ Search

[Listing your most used commands](https://remysharp.com/2019/10/08/listing-your-most-used-commands "Permanent Link: Listing your most used commands")

A fun little command line task is to retrospectively look back at all the commands you run to which you use all the time.

You’ll find similar solutions to this on sites like StackOverflow, but they’re not quite right. Since quite often commands are piped together the solutions generally ignore the piped commands. So here’s how to get it properly.

[![](/images/terminal-600.jpg)](https://training.leftlogic.com/buy/terminal/cli2?coupon=BLOG\&utm_source=blog\&utm_medium=banner\&utm_campaign=remysharp-discount)

[READER DISCOUNTSave $50 on terminal.training](https://training.leftlogic.com/buy/terminal/cli2?coupon=BLOG\&utm_source=blog\&utm_medium=banner\&utm_campaign=remysharp-discount)

[I’ve published 38 videos for new developers, designers, UX, UI, product owners and anyone who needs to conquer the command line today.](https://training.leftlogic.com/buy/terminal/cli2?coupon=BLOG\&utm_source=blog\&utm_medium=banner\&utm_campaign=remysharp-discount)

[$49 - only from this link](https://training.leftlogic.com/buy/terminal/cli2?coupon=BLOG\&utm_source=blog\&utm_medium=banner\&utm_campaign=remysharp-discount)

The command[](#the-command)

It’s quite a long chain, and parts will be consistent with other examples on the web, but it’s my awk commands that gets the finer detail:

$ history |
  awk 'BEGIN {FS="\\|"; OFS="\n"} { $1=$1; gsub(/^[0-9* ]+/, ""); print $0 }' |
  awk '{ $1=$1 } /^[a-z]/ { print $1 }' |
  sort |
  uniq -c |
  sort -n

In plain text[](#in-plain-text)

Take all the history and split each line by the | pipe character.

Then print each record on a new line (from the split line) and strip leading numbers.

Then trim the result, take the first word on each line, throw away results that contain symbols (for instance, a command won’t lead with a *), then sort by the unique count.

Command breakdown[](#command-breakdown)

The commands can be broken down into three groups: history, text manipulation, counting.

The real work is happening in the text manipulation under the awk. Let’s look at the first awk command:

# program setup
BEGIN {
  # Field Separator: split lines on the | (the double \\ escaping |)
  FS="\\|";

  # Output Field Separator: join the fields by new lines
  OFS="\n"
}

{
  # this is weirdness of awk, but it recalcs $0 to contain all fields
  $1=$1;

  # strip leading numbers from history input and trailing * character
  gsub(/^[0-9* ]+/, "")

  # print output (joined by OFS - "\n")
  print $0
}

This generates a new output that contains lines with the commands used either at the start of the command or directly after the pipe operator. But the output still includes all the command line arguments, so now we want to pluck the first token in the line.

However, before printing the line, we need to remove leading spaces and the only print lines that start with a letter (since there might be some stray arguments included in our list):

# strip leading and trailing white space "magic"!
{ $1=$1 }

# filter results so that only lines starting a letter match
/^[a-z]/

# print the first token (awk space separates by default)
{ print $1 }

Now our output is a long list of single word commands and we’re ready to get the count:

$ sort |  # for uniq to work, results must be sorted
uniq -c | # count and print unique results
sort -n # sort numerically (by the first column)

My most used commands[](#my-most-used-commands)

My history is configured as such:

$ # timestamps for later analysis. www.debian-administration.org/users/rossen/weblog/1
export HISTTIMEFORMAT='%F %T '

# keep history up to date, across sessions, in realtime
#  http://unix.stackexchange.com/a/48113
#   - ignorespace = don't save lines that begin with a space
#   - ignoredups  = don't save duplicate lines
#   - erasedups   = erase across sessions
export HISTCONTROL=ignorespace:ignoredups:erasedups
export HISTSIZE=100000                          # big big history (default is 500)
export HISTFILESIZE=$HISTSIZE                   # big big history
which shopt > /dev/null && shopt -s histappend  # append to history, don't overwrite it

Which means I’ve got 100,000 records in my history (synced across all my sessions).

So my most used command line programs, in the last 100,000 commands are:

 127 wm      # my webmention tool: https://webmention.app
 131 code    # vs code
 139 nodemon # https://github.com/remy/nodemon
 153 ssh     # connecting or running remote commands
 162 ack     # alternative to grep https://beyondgrep.com/documentation/
 163 mkdir
 171 mv
 198 z       # zsh alias to jump to directory
 199 fd      # alternative to find https://github.com/sharkdp/fd
 217 rm
 219 now     # deployment with zeit.co
 225 history
 235 node
 247 npx     # running node_modules/.bin programs
 319 cat     # actually aliased to bat https://github.com/sharkdp/bat
 371 ls
 664 cd
 787 curl    # usually testing APIs
 819 npm     # install, start, dev and test
1654 git     # most of my git is done on the cli

What about you?

πŸ‘ 14 likes

[![Bramus!](/images/no-user.svg "Bramus!")](![Pedro Martins(/images/no-user.svg "Pedro Martins")](![Steven Beeckman(/images/no-user.svg "Steven Beeckman")](![Jim Gibbs(/images/no-user.svg "Jim Gibbs")](![Sue(/images/no-user.svg "Sue")](![PJ Khalil(/images/no-user.svg "PJ Khalil")](![𝒡𝑒𝓋 π’œπ“‹π‘’π“‡π’·π’Άπ’Έπ’½(/images/no-user.svg "𝒡𝑒𝓋 π’œπ“‹π‘’π“‡π’·π’Άπ’Έπ’½")](![Ryan Dunckel(/images/no-user.svg "Ryan Dunckel")](![James Wright(/images/no-user.svg "James Wright")](![Andy Davies(/images/no-user.svg "Andy Davies")](![Jonathan Fielding(/images/no-user.svg "Jonathan Fielding")](![Naomi Freeman(/images/no-user.svg "Naomi Freeman")](![Michael Mifsud(/images/no-user.svg "Michael Mifsud")](![Holger Bartel(/images/no-user.svg "Holger Bartel")](https://twitter.com/foobartel)

Comments

Lock Thread

Login

Add Comment[M ↓ Β  Markdown]()

[Upvotes]()[Newest]()[Oldest]()

0 points

4 years ago

Strange, your awk command only seems to work with the default history, if you run it with export HISTTIMEFORMAT='%F %T ' in your profile it breaks. I think your first awk command needs to have gsub(/^[0-9* -:]+/, "")

Here are mine - pt (the platinum surfer) is an alternative to ag, itself an alternative to ack - but faster and with better documentation, try it out!

    263 anki.py
    263 npm
    281 la # ls -laF --color
    305 cd
    336 code # visual studio code
    549 find
    614 yarn
    632 node
    652 gs # git status
    718 git

SelΓ§uk CΔ°HAN

0 points

4 years ago

   8 touch
  11 rm
  14 ls
  15 aws
  18 docker-compose
  21 cd
  24 npm
  27 clear
  46 curl
 161 git

0 points

4 years ago

I love that clear is in your top 3! Assuming it’s a command on its own, ctrl+l (ell) is a great shortcut as a replacement.

0 points

4 years ago

Nice!

Here’s mine:

    319 jq # JSON processor, https://github.com/stedolan/jq
    321 python
    365 gco # alias for `git checkout`
    402 awk
    403 vim
    424 curl
    746 grep
    994 cat
   1243 gc # alias for `git commit`
   1658 git

0 points

4 years ago

That’s ace mate, love the explanation of each command as well.

Here’s my top ten:

  29 l # custom alias for `ls -lF`
  32 hs # custom alias for 'hexo serve'
  38 yarn
  56 o # open finder
  56 theme # shopify
 138 git
 142 z
 150 s # open sublime text
 178 cd
 259 npm

[Commento](https://commento.io)