Searching your bash history
Ever forget the exact syntax to that obscure bash command you ran weeks ago, or even that standard command you ran just yesterday? Then history
is coming to the rescue.
Rather than having to disrupt your workflow and start Googling for that same stackoverflow post you visited way back, history
will print out your full bash history in your terminal with all the commands you’ve ever executed, like shown in the sample below:
11827 dcu
11828 ll
11829 touch article.md
11830 nn article.md
11831 nk article.md
11832 history
11833 hg scp
11834 man history
11835 history
11836 cd ~
To execute one of the outputed commands in question, just take its number preceded by !
, like !11827
, and it will print out the command for you (or you can just copy it directly from the terminal output).
grep your history
But, what if you have thousands of bash commands and don’t want to scroll through all of them? Well, then we can just pipe the output to grep and search through it that way like with the below:
history | grep whateverimlookingfor
To make things even easier, we can move the history | grep
command into an alias defined in our .bashrc
file (or .zshrc
if using the zsh shell) as shown below:
alias hg="history|grep "
After refreshing your terminal or sourcing your .bashrc / .zshrc file, searching your history is as easy as running hg searchterm
. For example, we can run hg scp
to get the full syntax to that scp
command that I've used multiple times but still don't have memorized.
7589 scp sfh:/root/.ssh/authorized_keys .
8045 scp zcrawler.sql ollie@198.199.98.165:/var/www
8156 scp ollie@198.199.98.165:/var/log/syslog1 .
8167 scp ollie@198.199.98.165:/var/log/syslog .
8168 scp ollie@198.199.98.165:/var/log/syslog.1 .
multi term history search
The above hg
alias is already a huge lifesaver for quickly digging up previous commands (which I know worked), rather than having to go digging through notes or Google to find things that I ran days / weeks / months / years ago. But just grepping through the history is a bit limited. For instance, what if we want to search for multiple search terms? Say I want to find a curl command, specifically made to port 9200? Well, then I can just grep again, by running something like below:
hg curl | grep 9200
While the above example will get the job done, it's not all that user-friendly, especially if we want to add even more search terms. We really need a fuzzy search option. Introducing fzf: https://github.com/junegunn/fzf
fuzzy match history search with fzf
The awesome fzf tool is easy to install on OSX using homebrew:
brew install fzf
# To install useful key bindings and fuzzy completion:
$(brew --prefix)/opt/fzf/install
Running both lines above will not only install fzf
, but the second line will also automatically map it to some useful things, chief among them is ctrl + r
. Running ctrl + r
in your OSX terminal will normally allow you to search through your history by default, but only one line at a time and without fuzzy matching, making it pretty limited. But with fzf
installed and the $(brew --prefix)/opt/fzf/install
run, typing ctrl
+ r
will bring up fzf
's awesome multi-line fuzzy history search like shown below:
11687 curl -s http://localhost:9200/history/_search\?q\=curl | jq '.hits.hits[]._source | "\(.number) \(.command)"'
11688 curl -s http://localhost:9200/history/_search\?q\=curl | jq -r '.hits.hits[]._source | "\(.number) \(.command)"'
11689 curl -s http://localhost:9200/history/_search\?q\=curl | jq -r '.hits.hits[]._source | "\(.number) + " " + \(.command)"'
11690 curl -s http://localhost:9200/history/_search\?q\=curl | jq -r '.hits.hits[]._source | "\(.number) \(.command)"'
11691 curl -s http://localhost:9200/history/_search\?q\=curl | jq -r '.hits.hits[]._source | "\(.number)" + " " + "\(.command)"'
11692 curl -s http://localhost:9200/history/_search\?q\=curl | jq -r '.hits.hits[]._source | "\(.number)" + " test" + "\(.command)"'
11693 curl -s http://localhost:9200/history/_search\?q\=curl | jq -r '.hits.hits[]._source | "\(.number)" + " test " + "\(.command)"'
> 11694 curl -s http://localhost:9200/history/_search\?q\=curl | jq -r '.hits.hits[]._source | "\(.number)" + " " + "\(.command)"'
255/11840 +S
> curl localhost 9200
Now we can search through our entire bash history and easily find the exact command we were thinking about! It definitely beats having to open up Chrome and track down the stackoverflow answer you used one time back in the day. Check it out if you haven't already.
< Home