It's simple using interactive history expansion (needs set -H, which is the default in interactive sessions).
Important note: while you're experimenting with history expansions (and even if you're not experimenting), I suggest you turn on the histverify shell option with
shopt -s histverify
With this option turned on,
history substitutions are not immediately passed to the shell parser. Instead, the expanded line is reloaded into the Readline editing buffer for further modification.
(Quote from the Bash Reference Manual). In fact, I even suggest you put shopt -s histverify in your .bashrc.
If you typed
rm dir1 dir2
you got an error; in fact you meant rm -r dir1 dir2, here's how you can fix the command:
You want to replace the string rm with rm -r:
!!:s/rm/& -r/
Explanation.
!! refers to the last command (it's much safer to use !! than to use !, since !! forces the substitution to be performed on the previous command, and not on a matching previous command; just in case). The column (:) is the character that separates the event designator (here !!) from the word designator (that is unused—empty—here) and the modifier.
- The modifier used here is
s/rm/& -r/ which means: replace (the first) occurrence of rm and replace it with itself (&) followed by -r.
When you type this (and with histverify turned on), you should have the following line in your readline buffer:
rm -r dir1 dir2
ready to fire, with the cursor at the end of the line. The same can be achieved by repeating the command rm and not using &:
!!:s/rm/rm -r/
Same as above in shorter form: a shortcut for
!!:s/old/new/
is
^old^new^
hence, you could have typed this instead:
^rm^& -r^
It's more cryptic and will certainly impress your little sister.
You want to keep all the arguments (here dir1 and dir2) and replace the command (i.e., the 0-th word) with a new one (here, replace the command rm with rm -r):
rm -r !!:1-$
Explanation. The !! refers to the last command and the column is the separator, as before. But now, we're selecting the range of words 1-$, i.e., the first to the last (indexing starts at 0, so that the command rm is the 0-th word). Very handy to run a new command with the old arguments.
Same as above using a shortcut:
rm -r !!:*
That's right, * is a shortcut for the range 1-$.
There's much more to what I gave here; I hope it's a good start for you to understand and experiment with the material provided in the reference manual.
In your specific case, namely
rm ./somedir
I wouldn't even bother with history expansions at all: shells have the special variable _ that expands to the last argument of the previous command. So typing
rm -r "$_"
would fix that! but this only works with the last argument of the last command… for more arguments, you'll need to use the interactive history facility.