Something better than history | grep: fzf

I started using UNIX when I loaded the 7th edition nine-track tape onto a PDP-11 in a university lab. The shell — bin/sh or as we put it back then, sh(1) — had a history command that would regurgitate recent command lines. I got in the habit of typing history | grep whatever to find a recent command, then typing !123 (or whatever number appears next to the command I want) to run it again. The history is a helpful way to re-use commands without sweating the precise syntax again.

That was in 1975. And I’ve been doing it that way ever since. I know, lame, huh? Recently some people introduced me to a better way. First of all, in /usr/bin/bash I can type <ctrl>-r and then type a few characters, and it will search the history. I can pick a particular command with the up and down arrow keys. I then hit <enter> and the command I chose appears on the command line ready for editing, or running iwth another <enter>. I didn’t know that and now I do. Cool.

Second, there’s fzf — a Command Line Fuzzy Finder program by Junegunn Choi. This program, written in golang, presents a display of items — filenames, previous commands, whatever — in the terminal. Typing a few characters narrows the choices with a search function, and the arrow keys pick an item. Then <enter> chooses the item and puts it onto the command line.

fzf can be integrated with /usr/bin/bash to handle command history. I simply put this line into my .bashrc file.

eval "$(fzf --bash)"

Now, when I type <ctrl>-R I get the fuzzy-finder keyboard user interface, with fuzzy searching of my command history. It’s great.

Installing fzf

As of mid-March 2025 the version of fzf we get on Ubuntu with sudo apt install fzf doesn’t yet have the feature needed for easy integration with /usr/bn/bash. So I had to download the appropriate compiled binary from the project’s GitHub Releases page and extract the binary from the provided .tar.gz file. Then I put it into my system with these commands.

sudo chown root:root fzf
sudo mv fzf /usr/local/bin/

Finally putting this line into .bashrc enables the <ctrl>-R integration.

eval "$(fzf --bash)"

Now I just have to train my old fingers to do things the new way.

Leave a Comment