2018/11/07: bash history expansion

In the world of UNIX-like operating systems, there are quite a few corners where it takes years till one starts using them for real for the first time—and soon afterwards wonders how one ever could do without. find(1) is such a tool, and the bash history expansion is another such feature. By the latter, I'm not talking about readline-wrapping (what allows access to the history via Ctrl-R) but proper history expansion (which expands, by default, the exclamation point to certain parts of the history) as described in the section by that name in the man page. As the man page describes the mechanism precisely, there is no point in repeating it; instead, this post intends to motivate reading this part of the man page by giving some examples on how history expansion might be used.

I actually need the output of the last command

Often, using find(1) is a great way, to find a particular file in a large source tree (e.g., if I just remember the name, but not the location). But then, after confirming that it was indeed the file I was looking for, I want to edit the file.


$ find . -name git.bzl
$ $EDITOR $(!!)

cvs rm

cvs(1) requires, for the rm command, that the respective files already be removed in the checkout. Some people do not like that, arguing that they lack tab-expansion when composing the cvs rm command.


$ rm some/file/foo another/file/bar
$ # ...test that things work...
$ cvs !rm

preparing a patch

A build fails and you have to prepare a patch.


$ view the/file/that/caused/trouble.c # yes, what I suspected; easy to patch
$ cp !!:1 !!:1.orig
$ vi !!:1 # change
$ diff -u !!:1.orig !!:1

do a dry-run first

Sometimes, the git command-line can be confusing, so better do a --dry-run first.


$ git push origin foo-feature -f --dry-run
$ !!:0-

more from the same directory

Copied a file with a long path (so that, even with tab-expansion, entering it takes a while) and then realise, you need another file from the same directory?


$ cp /some/very/long/path/foo.txt .
$ cp !!:1:h/bar.md .