One of my favorite time-saving commands in Bash is !$ which recalls the last argument of the last entered command. This is incredibly useful in situations like this:
$ mkdir superlongnamethatidontwanttotypeout
$ cd !$ && pwd
superlongnamethatidontwanttotypeout
Similarly, !! recalls the entirety of the last command and !-2 recalls the next to last command from history like so:
$ touch example1
$ touch example2
$ !-2
touch example1
This can be extended out with negative integers to go back lines in Bash history, or a positive integer to start from beginning.
Note: If you need more functionality, you should really learn the
fcbuiltin command. It lets you yank a range of commands from history likefc -2 -4, throws it in your$EDITORfor review, and then execute the command on exit.
With the !-2 logic in mind, I thought !$-2 would work but you get the following result:
$ touch example1
$ touch example2
$ vim !$-2
vim example2-2
As you can see, that expands the last argument and then just inserts -2 instead of interpreting it as a negative line number as I want. I thought this was odd so I researched more and realized that I had a fundamental misunderstanding of how !$ works.
The Bash Manual says:
!!:$designates the last argument of the preceding command. This may be shortened to!$.
So $ is actually an event specification on !! and thus !$ is not a completely separate word designator from !! as I thought. Knowing that, we just need to use !-2$ like so:
$ touch example1
$ touch example2
$ vim !-2$
vim example1
This gets us the last argument of the next to last command and can also be modified to grab different lines like the !-2 command.
Note:
$_is another beast entirely as it works on executed commands and not entered commands like!$who needs something to be in history for it to work.
Bash History is an incredibly deep topic with a lot of interesting shortcuts. If you want learn more, I would suggest setting shopt -s histverify to get a better picture of how the shell interprets your commands.