Reputation: 123
I couldn't find an answer for this exact problem, so I'll ask it.
I'm working in Cygwin and want to reference previous commands using !n
notation, e.g., if command 5 was which ls
, then !5
runs the same command.
The problem is when trying to do substitution, so running:
!5:s/which \([a-z]\)/\1/
should just run ls, or whatever the argument was for which for command number 5.
I've tried several ways of doing this kind of substitution and get the same error:
bash: :s/which \([a-z]*\)/\1/: substitution failed
Upvotes: 1
Views: 698
Reputation: 52858
This worked for me using Bash in Cygwin (note that my which ls
command was number 501 in my history list; not 5
like yours):
$(!501 | sed 's/which \([a-z]\)/\1/')
You could also do it this way (which is shorter/cleaner):
$(!501 | sed 's/which //')
Upvotes: 0
Reputation: 361605
As far as I can tell the s/old/new/
history substitution syntax only does simple string substitution; it does not support full regexes. Here's what man bash
has to say:
s/old/new/
Substitute new for the first occurrence of old in the event line. Any delimiter can be used in place of
/
. The final delimiter is optional if it is the last character of the event line. The delimiter may be quoted in old and new with a single backslash. If&
appears in new, it is replaced by old. A single backslash will quote the&
. If old is null, it is set to the last old substituted, or, if no previous history substitutions took place, the last string in a!?string[?]
search.
Never fear, though. There are in fact easier ways to accomplish what you are trying to do:
!$
evaluates to the last argument of the previous command:
# ls /etc/passwd
/etc/passwd
# vim !$
vim /etc/passwd
!5:$
evaluates to the last argument of command #5:
# history
...
5: which ls
...
# !5:$
ls
You can also use Alt+. to perform an immediate substitution equivalent to !$
. Alt+. is one of the best bash tricks I know.
Upvotes: 3