Suppose you’ve typed a long command and you need to rerun it with a small modification. Say you need to replace
bar. Bash will let you do this with
^foo^bar^. And although you’re supposed to put the final caret on the end, it will let you get by without it.
$ echo foo foo $ ^foo^bar bar
Great. Now suppose
foo appears twice in a command.
$ echo foo foo foo foo $ ^foo^bar bar foo
Surprise! Only the first
foo gets replaced.
The way to fix this is to use
!:gs/foo/bar/ to do a global replacement, i.e. to replace all instances of
bar. If you really only want to replace the first instance of
foo then use the same command without the
$ echo foo foo foo foo $ !:gs/foo/bar/ bar bar $ !:s/foo/bar/ bar foo
You can leave off the final slash and everything will still work.
What about zsh?
The zsh shell works a lot like bash, so much that I forget that I’m using zsh until something unexpected happens. “Oh yeah, I’m on my Mac . This is zsh and not bash.”
So how do the examples above run under zsh? The simple substitution
^foo^bar to replace the first instance of
bar works just the same.
However, zsh offers another possibility, one that isn’t supported in bash. You can append
:G to the substitution command with carets.
% echo foo foo foo foo % ^foo^bar^:G bar bar
Here the final caret is critical. Without it you replace the first instance of
These features are well documented, but it’s hard to find the documentation if you don’t know the buzzword to search for. If you try searching on “string replacement” and things like that, you’re likely to find other things that what you’re looking for.
For bash, the magic phrase is “event designator.” If you type
man bash and scroll down to the section entitled Event Designators you’ll find everything mentioned here and more. On zsh the magic phrase is “history expansion.”
- The hard part in becoming a command line wizard
- Set theory at the command line
- Random sampling from a file
 I use bash on Linux and zsh on Mac. When in Rome, do as the Romans do. Though I do remap a few keys in order to use muscle memory across platforms.
One thought on “Repeat shell command replacing a word”
This is the kind of command line fu I struggle to teach colleagues and clients.