It's ironic that the standard one-liner for this uses a pipeline but only counts the first word of the first command of the pipeline. Given itself as input, "sort" ought to be the most used command, but "history" is the only one counted. (I bring this up not for the sake of standard HN nitpicking but to point out that you probably do want to cover at least `sort` in your workshop, and it will be underrepresented in these results, along with `grep`, `wc`, etc.)
Unfortunately, shell grammar is complex enough that a correct one-liner is probably infeasible. For example, one of my top "commands" if you count by words is an environment variable setting prepended to an actual command.
EDIT: you can get good enough results by just splitting on "|", as others have suggested here -- any parts of regular expressions, etc that aren't really commands will probably be infrequent enough to get lost in the noise, and treating || as containing an empty command won't hurt. If you're going to catch ||, though, might as well get && too... and now you're going down the rabbit hole :-)
Quick hack - you can include the commands you pipe to with this:
history \
| sed "s/^[0-9 ]*//" \
| sed "s/ *| */\n/g \
| awk '{print $1}' \
| sort \
| uniq -c \
| sort -rn \
| head -n 100 \
> commands.txt
I haven't tried to account for pipe symbols inside strings - it didn't seem work it.
In case there are commands you want then to exclude (which I do) then you might want to "head -200", remove the commands you don't want to provide, and then trim to 100.
Added in edit - having done this a good half of my top 100 are actually scripts, so this is pretty pointless for me unless I rummage through them to find the common commands.
Added in edit again:
OK, here's a version that only includes actual system commands, and hence filters out all my personal scripts and commands:
history \
| sed "s/^[0-9 ]*//" \
| sed "s/ *| */\n/g" \
| awk '{print $1}' \
| xargs which \
| sed "s.^/usr.." \
| grep ^.bin \
| sed "s/^.*\///" \
| sort \
| uniq -c \
| sort -rn \
> commands.txt
I think you want s///g on your second sed... Also that doesn't work in Mac OS X for some reason (their sed doesn't appear to interpret \n in the replacement text). I replaced it with perl to make that part work:
perl -pe 's/ *\| */\n/g'
I still haven't gotten the whole thing to work yet because my history contains the above history pipeline and so it's splitting the "|" that inside the sed command onto multiple lines which is causing "xargs which" to balk because quotes are not matching or something:
xargs: unterminated quote
Shells are amazing until spaces or quotes are involved! :-)
Not too difficult to guess what I'm doing. I also use a lot of sed, grep, xargs and such, but they're typically are piped and don't show up here. I removed some local scripts from here that won't make sense to others.
"git status -sb" and "git add -p", respectively. Most of the 1-3 letter ones are git aliases (and notice how often I use them!), corresponding to the aliases here: https://github.com/kivikakk/dotdirs/blob/master/gitconfig#L3... (some rubbish in my .zshrc makes it such that "a -> git a")
Be careful if you are in the habit of using environment variables to specify API keys or database passwords. One of my top commands is `FACEBOOK_SECRET=...`.
It might just be my OCD showing, but 'clear' is my number one by an order of magnitude.
next 20:
177 ls
167 cd
122 brew
120 vim
119 cabal
117 cindy (an alias for ssh'ing to my local dev box)
115 sudo
114 tmux
111 man
110 less
110 openssl
109 rm
108 whois
107 ghci
107 lein
106 ssh
86 strings
75 smbclient
75 racket
65 nc
My history file is de-duplicated (oh-my-zsh enables hist_ignore_dups), so this sort of approach is never accurate.
Git comes out on top, but presumably because most of my invocations are unique ("git commit -m ..."), while things like "ls" are farther down the list.
Unfortunately, my history settings mess with my results. Commands that are three letters or less just get ignored. Identical commands repeated in succession are also only counted once.
Excellent point. I'm definitely going to put that caveat at the beginning of any analysis I post. (and thanks to ctrl_freak for posting an alternative!)
738 ll (alias for a more reformed `ls` output)
549 python
457 cd
397 git
173 exit
157 vim
150 less
142 ssh
122 ./synchVeiled.sh ( script I'd been using a lot for a project )
121 sudo
109 scp
109 fab
101 gca ( alias for "git commit -am" )
97 curl
88 bash
74 grep
68 startx
56 rm
56 lguf ( alias to show all files in a git repo that are not being tracked )
55 history
54 whois
49 htop
48 source
40 echo
39 foreman
This would be fantastic if all it had was the instructions to see your own top commands. What a great way to discover opportunities for automation and time saving!
Many of my top commands are 1- or 2-letter aliases. g for git, v for vim, and so forth.
I had to change the command slightly to work with zsh -- instead of 'history' I did 'history 1' to get the full (10k entries for me) history instead of the most recent 16.
I run wildly different commands on different hosts so I actually took three hosts I'm often logged into and combined their most run commands in history into one 100 line file.
Super-facile gpm plopping grabs across six nox tty consoles onto emacs and as apps arguments is the most pleasant, productive, and relaxed user interface I know.
Unfortunately, shell grammar is complex enough that a correct one-liner is probably infeasible. For example, one of my top "commands" if you count by words is an environment variable setting prepended to an actual command.
EDIT: you can get good enough results by just splitting on "|", as others have suggested here -- any parts of regular expressions, etc that aren't really commands will probably be infrequent enough to get lost in the noise, and treating || as containing an empty command won't hurt. If you're going to catch ||, though, might as well get && too... and now you're going down the rabbit hole :-)