zsh: Bang History Word Substitution
Yes, your job is repetitive, and typing a series of git add
,
git commit
and git push
doesn't help.
When I need to redo something I've already done, usually I just hit
the up-arrow key if the shell command was recent (like one or two
commands ago), or type Control-R
and followed by some keyword on the
command line. Sure, this approach often requires multiple Control-R
keystrokes until I would get to the right command, but this feature
has served me well for thousands of years.
This is why I never bothered with the bang history substitution
approach, e.g. !43
to repeat the 43rd command entry. But I just
learned about word substitutions while perusing the zshexpn
man
page.
Let's assume you've done the following commands:
$ git add src/main/resources/nav/unified/templates/nav.handlebars
$ git commit -m "Fixed bug #249, and well, you know. . ."
$ git push origin HEAD:refs/publish/development
Now, with the next bug on your queue, you want to edit that same
file, but copying/pasting is so 1984. Type this:
$ echo !-4:2
You can now either hit Return
or Tab
, and that filename shows
up after the echo
command. Pretty slick.
How does it work? Well the -4
says, grab the 4th previous entry††Yes, it is the fourth since what you are typing now is always -1
.
The :2
part says, grab the second argument to the command, in this
case, the filename.
But who wants to count the history? Try this on for size:
$ echo !git:3
This echoes the third argument to the last git
command you typed, in
my particular example, that would be the remote branch name.
But how to get that filename four lines back without counting? How about:
$ echo !?add?:$
This looks through the history until it finds an add
parameter (in
this case, attached to the git
command), and then brings back the
final argument (that's what the :$
tells it).
Here is a snippet from the Zshell man page (zshexpn
) for all of the
Word Designators:
0
The first input word (command).
n
The nth argument.
ˆ
The first argument. That is, 1.
$
The last argument.
%
The word matched by (the most recent) ?str
search.
x−y
A range of words; x
defaults to 0
.
*
All the arguments, or a null value if there are none.
x*
Abbreviates x−$
.
x−
Like x*
but omitting word $
.
Note that a %
word designator works only when used in one of !%
,
!:%
or !?str?:%
, and only when used after a !?
expansion
(possibly in an earlier command). Anything else results in an error,
although the error may not be the most obvious one.
Tell others about this article: