Suppose you’ve typed a long command and you need to rerun it with a small modification. Say you need to replace foo
with 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 foo
with bar
. If you really only want to replace the first instance of foo
then use the same command without the g
.
$ 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 [1]. 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 foo
with 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 foo
with bar:G
.
Event designators
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.”
Related posts
- The hard part in becoming a command line wizard
- Set theory at the command line
- Random sampling from a file
[1] 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.
♥️
This is the kind of command line fu I struggle to teach colleagues and clients.