I finally mastered the shell (beit bash or zsh, but really, this is readline)’s history with command replacement. It took me 19 years and my entire family fortune to gather enough wits to read that part of the manual with enough attention and will as to learn to use it.

Essentially, you can recall previous commands from the history with !number. You can then change some content of the previous command programmatically before running it by adding :s/PATTERN/REPLACEMENT/ or :gs/PATTERN/REPLACEMENT/ (the first one will replace the first occurrence, the second one will replace them all).

So, without further ado,

$ echo aaa bbb aaa      # original command
aaa bbb aaa
$ history | tail  -n 1  # get the number of that last command in the history
 970  echo aaa bbb aaa
$ !970:s/aaa/ccc   # ask the shell to replay it, replacing the first occurrence of `aaa` with `ccc`
$ echo ccc bbb aaa   # the shell (zsh) put that here for me
ccc bbb aaa
$ history | tail  -n 2  # look at the history now
 970  echo aaa bbb aaa
 972  echo ccc bbb aaa
$ !970:gs/aaa/ccc   # now replace all occurrences of `aaa` with `ccc`
$ echo ccc bbb ccc   # thanks, shell
ccc bbb ccc

I’ve always triggered that behaviour by mistake, and my fingers would never fall in the right way when I needed it before. Those times are gone!

As I pointed this out at work, Scott Hugues further elaborated that you can also do this much faster if you want to reuse a version of the last command you ran.

$ echo aaa
aaa
$ ^aaa^bbb
echo bbb
bbb

Good times.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.