I'd like to replace a word in my most recent command with a new word.
For example, I just ran
> scp -r local_dir_A/ mydomain.com:directory/
and now I want to do
> scp -r local_dir_B/ mydomain.com:directory/
I can do it with a substitution, but it requires actually explicitly
typing "local_dir_A" again:
> ^local_dir_A^local_dir_B^
Is there some quick way to tell the substitution to use the 2nd
argument of the previous command?
After reading documentation, I've tried the following:
> ^:2^local_dir_B^
> ^2-2^local_dir_B/^
> ^!!2-2^local_dir_B^
> ^!2^local_dir_B^
> ^!2-2^local_dir_B^
> !!:s%:2%local_dir_B/%
> !:s%:2%local_dir_B%
> !:s%!:2%local_dir_B%
These all result in "substitution failed"
Any help is appreciated.
Thanks in advance!
- Rob
> I'd like to replace a word in my most recent command with a new word.
>
> For example, I just ran
>
> > scp -r local_dir_A/ mydomain.com:directory/
>
> and now I want to do
>
> > scp -r local_dir_B/ mydomain.com:directory/
Responding on a machine with no bash, so unable to test,
and this is not exactly what you're looking for, but
I would do that (with readline set to vi key-bindings):
<esc>kfArB
(or, slightly longer and more explicit):
<esc>k2WcfAlocal_dir_B
I realize you're looking for a substitution, but
I find it's usually easier to do this sort of thing.
With emacs key-bindings, you can do something
similar, but you'll probably have to resort to using the
arrow keys to get the cursor in the right place.
Thanks for the ideas; I use emacs bindings, but I can basically see
you've perfectly answered my question.
However, I wrote "local_dir_A" and "local_dir_B" to simplify the
question. The names were actually "escalators" and "line_signs" and
"lower_fire_exit" respectively.
In the actual cases that I wanted to do, it looks like the command
above would require typing the old words in order to explicitly
identify and replace them.
For now I can continue with the equivalent expression using emacs
bindings. But if anyone can give the syntax for a replacement that
doesn't require typing the old word, that would be great great great.
Just to be clear on my attempts above:
> ^:2^local_dir_B^
> ^2-2^local_dir_B/^
> ^!!2-2^local_dir_B^
> ^!2^local_dir_B^
> ^!2-2^local_dir_B^
> !!:s%:2%local_dir_B/%
> !:s%:2%local_dir_B%
> !:s%!:2%local_dir_B%
I'm trying to tell the replace command to use the 2nd word as the
first item to replace.
You can certainly do this using a number of different key sequences.
The core of the solution involves using the readline function
`yank-nth-arg' with a numeric argument:
$ echo foo bar baz quux
foo bar baz quux
$ !!:s/baz/junk
echo foo bar junk quux
foo bar junk quux
The third line above was typed like this:
! ! : s / M-3 C-M-y / j u n k RET
I have C-M-y bound to `yank-nth-arg' via this setting in my
${HOME}/.inputrc file (though bash(1) indicates that this is the
default binding):
Control-Meta-y: yank-nth-arg
The M-3 (which is bound to the readline function `digit-argument')
simply provides the argument of '3' to `yank-nth-arg' to select 'baz'
for the field to be replaced.
Note that the arguments from the previous command line are zero
indexed; using M-0 instead of M-3 would have replaced 'echo' instead of
'baz'; likewise, using M-4 instead of M-3 would have replaced 'quux'.
The other ways to do this simply involve variations on the above: use
the ESC as a prefix key instead of Meta, and invoke the
`universal-argument' readline function instead of `digit-argument'. In
my ${HOME}/.inputrc file I aslo have this binding:
Control-Meta-u: universal-argument
So the remaining variations of the above are:
! ! : s / ESC 3 C-M-y / j u n k RET
! ! : s / ESC 3 ESC C-y / j u n k RET
! ! : s / C-M-u 3 C-M-y / j u n k RET
! ! : s / C-M-u 3 ESC C-y / j u n k RET
HTH,
-Al
P.S. As an aside, my early tests in 'xterm' version 222-1etch2 on my
Debian box, I was initially only able to get the above examples to
work when 'xterm' was launched with LANG=C, but not with
LANG=en_US.UTF-8. With the latter tests, only those key sequences
that used ESC to obtain the numeric argument were working. By
contrast, all examples worked as expected on the Linux console.
A bit of googling turned up the "Meta keys and locales" section in
this:
http://www.astro.caltech.edu/~mcs/tecla/tecla.html
I needed to add the following to my ${HOME}/.Xresources:
XTerm*metaSendsEscape: true
--
-----------------------------------------------------------------
a l a n d. s a l e w s k i sale...@worldnet.att.net
1024D/FA2C3588 EDFA 195F EDF1 0933 1002 6396 7C92 5CB3 FA2C 3588
-----------------------------------------------------------------
I am thrilled to say that the above sequence worked with zero
modification to any setup on my machine. Actually I typed
^ M-3 M-C-y ^ n e w ^ RET
I'm running OS X 10.4.1
Thank you for the huge level of detail in your answer. I cannot
honestly say I understand it all, nor will I realistically use it, but
I hope your answer solves problems for millions of people.
It may take a while with the rate of posts on this group. ;-)
- Rob