Revert to the original command when you've have made multiple changes to the line:
revert-line (M-r)
Undo all changes made to this line. This is like
executing the undo command enough times to get back to the beginning.
M
is the meta key, which is alt</kbd+r for me.
Gratuitous, Yet Helpful Info
When you have executed a command like OP had previously done (it happens), there is nothing to "undo" because the commands are handled and remembered by the GNU Readline library and are not written to $HISTFILE
until the shell exits. The reason I mention this is because you can't just grep
the $HISTFILE
like one might expect and it may not be ideal to exit the shell.
So here are a couple of options to save you from scrolling back through all previous readline commands.
If you remember some of the command, press ctrl+r and type what you remember to search through previous commands containing that string. Pressing ctrl+r again will display the next most recent, searching backwards.
For example, type ls -l
then ctrl+r as many times as it takes to find the previous command you seek. If you scroll past it, ctrl+s will search forward from the current position.
The fc
bash builtin command is helpful to list the index numbers alongside previous readline commands.
fc -l -100
will list the previous 100 commands in readline.
Additionally, if OP knows he's looking for a previous ls -l
command, he could pipe the output to grep
such as: fc -l -100 | grep 'ls -l'
This should output a list of previous ls -l
commands preceded by an index number. The output looks like this:
2065 ls -l
Now you can use the event designator !n
where n
is the index number. In this example, executing !2065
will expand to ls -l
.
Although it doesn't help after the fact, anyone looking to preserve the recent command history when modifying previous commands should see the HISTORY EXPANSION
section of man bash
. Here are some alternative methods for modifying old commands without overwriting the history.
The Event Designators
section shows how you can easily edit string from the most recently used command.
^string1^string2^
Quick substitution. Repeat the previous command, replacing string1 with string2. Equivalent to
``!!:s/string1/string2/'' (see Modifiers below).
Example:
$ echo foo
foo
$ ^foo^bar
echo bar
bar
The most recent commands will now show:
echo foo
echo bar
The above example also explains how to use sed
to replace a string in an event designator.
!-n Refer to the current command minus n.
So if 3 commands up in the history is echo foo
then you would use:
!-3:s/foo/bar
Note that event designators will appear in your history as the command executed, in this case echo bar
. It will not appear in the history as !-3:s/foo/bar
.
Just throwing that out there as it seems closely related, even if it is more of a "don't do" than the "undo" solution OP is looking for.
ksh
, for example, you can edit history entries and invoke them without deleting the "previous version" of the entry; you have all invoked commands available. – Janis Apr 30 '15 at 12:16ksh
's behaviour differs here, it seems. And your history edit options also depend on the choosen editing mode. Inksh
's vi-mode, for example, the old entry is not overwritten, and I can also issue an undo command, like invi
, with 'u'. – Janis Apr 30 '15 at 12:33ksh
, but it is good to know such thing exists there. – fedorqui Apr 30 '15 at 12:50