Short answer: the builtin fc
(fix command) of bash
fc
is the command, built-in in the bash shell, made to edit & re-execute commands of the history.
It is present on CygWin too and it works on all the Linux distributions on which I tested:
fc -s '\'='/' -1
Some explanations
Some words more about why you are getting "substitution failed"
It seems that for the s
modifier is not (yet) implemented the substitution of the backslash character \
, that is the escape one. To be sure we should see the code, for example, of the gnu version of the bash history expansion (but there was the above command to obtain what you were trying to do...so I take it lazy....).
Some notes:
We are lead to think that it will work each RegEx we find working with sed
, but it is not guaranteed. The backslash is the escape character of the expansion and the problem is here. Moreover the behaviour of the expansion is related with the shopt
options, so we should start to see case by case...
When you paste the string cd C:\Foo\Bar
in your bash shell it will be expanded and it will appear for the interpreter as cd C:FooBar
; in this form it will be stored in the $_
internal variable too.
If you instead pasted cd "C:\Foo\Bar"
or cd 'C:\Foo\Bar'
in the $_
variable you should find C:\Foo\Bar
.
Since the History expansion is performed immediately after a complete line is read, before the shell breaks it into words, you may be tempted to start to use it with some bashism more or less plain, e.g., with some derivation from (maybe adding :p
or :q
, ""
, parsing and so on...)
!!:0 ${_//\\/\/}
This is the moment to remember that it is not safe to start to play with path and filenames, especially if they come from the windows clipboard (read in general the page Why not parse ls
?, it is essentially related with the possibility to use tab, spaces and newlines as correct characters for the file names and the directory ones...).
Moreover when you paste a text captured with the mouse, you may paste a leading space too. This may avoid that your command will finish in the history (it depends from the shell options...). If so your following !!
will be a not controlled command... (see an example in another answer). This is a unneeded tangible risk.
Conclusion
History expansions introduce words from the history list into the input stream, making it easy to repeat commands, insert the arguments to a previous command into the current input line, or fix errors in previous commands quickly.
If it is not easy I start to think we are doing something wrong ;-)
Ad nauseam: a little experiment
I've enabled histverify
in the shell then...
shopt -s histverify
echo C:\Foo\Bar
!!:s|C|D| {1,2}A
then I press Enter and as verified expansion I find
echo D:\Foo\Bar {1,2}A
then I press Enter again and it echoes
D:FooBar 1A 2A
This seems to indicate that the substitution failed
is generated in the history expansion processed before of the Brace expansion, so first of all, and it seems to confirm that the s
history modifier didn't (yet) process the substitution of the \
character as a real regex...
cd 'C:\foo\bar'
!!:gs/\\/\/
does work in zsh…fc -s '\'='/' -1
works under the Ubuntu LTS default bash. Let me know if it works under Cygwin too. I posted more words in the answer.!!:gs/\\/\//
. @Hastur 'sfc -s '\'='/' -1
gets the expected behavior. this might be a bug in bash.