A handy history expansion trick in Bash
Bash is packed with countless tricks that look really clever at first,
but then turn out to be not so practical or ergonomic.
I've been experimenting with some,
trying to force myself to use new things,
even if they don't come easily at first.
Among the many tricks I tried to memorize,
one that survived very well is history expension with !$
and <kbd>ESC .</kbd>
If you type !$
on the command line,
it will get replaced with the last argument of the previous command.
For example I find myself very often in this kind of situation:
svn status /long/path/somewhere/else
svn revert -R /long/path/somewhere/else
svn update /long/path/somewhere/else
svn log -l3 /long/path/somewhere/else
I do this kind of thing several times per day,
not necessarily with Subversion commands.
Even though tab completion helps for entering paths quickly,
very often it takes several tab stops to do so,
which still makes it a pain to reenter a long path.
!$
simplifies this a lot:
svn status /long/path/somewhere/else
svn revert -R !$
svn update !$
svn log -l3 !$
I was reluctant to learn this because I had a workaround that I was very used to:
- <kbd>Up</kbd> arrow to bring back to previous command
- <kbd>Control w</kbd> to copy the path argument
- <kbd>Control c</kbd> to cancel the command
- Type the new command, for example
svn revert -R
like above - <kbd>Control y</kbd> to paste the path argument
I admit that looks pretty awful now in retrospect.
!$
is relatively easy to remember, because !
is the common key for history related commands, and $
means "the end" in regular expressions.
Similarly, !^
would be replaced with the first argument in the previous command, and ^
means "the beginning" in regular expressions.
Somehow I don't need !^
that much in practice.
There's also !*
, which gets replaced with all arguments in the previous command, but not the command itself.
For the entire previous command line you can use !!
.
A drawback of !$
is that you won't see its value until you execute the command.
So if you want to edit it, you cannot, which can be annoying.
In that case you can use <kbd>ESC .</kbd> instead.
This will paste the last argument immediately,
so you can see it and edit it.
I like the idea of this better than !$
,
but pressing the <kbd>ESC</kbd> key is somehow less ergonomic for me.
Maybe I just need to get used to it.
Written by Janos Gyerik
Related protips
6 Responses
Nice tip! Did not know about !*
A little bit off top, but in zsh you can use tab to autocomplete !! , !$, !*
Thanks @dmitree! Yeah, definitely should check out zsh
, I hear very often of its powers.
Great time saver, I've used it for a while!
Also try Alt+.
to cycle through previous arguments.
I would prefer de xtagon trick, but there are a shortcut to cycle to next arguments
I did a whole video on these operators, for example what does !215:$:t do. https://www.youtube.com/watch?v=9wcBBuZ6H4w see also: http://shawnbiddle.com/bash/