There is a really handy parameter/variable expansion feature in BASH that I don't see for history. I've checked man pages for history and for BASH itself. Not there ...maybe I missed it.

Example: I use ssh a lot and I can do this with variable expansion.

host=foo@bar.org

Suppose I wanted to extract just the host -- rather, remove the username.

hostonly=${host##*@}

If I

echo $hostonly

I get:

bar.org

My question: Is it possible to do this with commandline history?

eg.,

Command 1:

ssh foo@bar.org

Command 2:

ssh gary@!!:##*@

This doesn't work, of course, but can someone confirm whether or not this type of pattern matching is available?

Thanks!

Bubnoff

link|improve this question

71% accept rate
In my examples, it is not particularly advantageous to do what I'm asking. Forget the character counts -- I'm basically just wondering about regex support in bash history substitution. Can it work similarly to variables, in other words. I know about quick s&r with carets as well as the !!:s/// form. Sorry for the confusion! – Bubnoff Mar 9 '11 at 2:54
feedback

2 Answers

A neat trick often missed by people is the r command (which is itself a special case of the fc command):

$ ssh foo@bar.org
(...)
$ r foo=baz

The more general case is

$ fc -s foo=bar ssh

which lets you select a command from the history by substring, then perform the specified substitution and run it. If you leave off the -s, it will load the command into $EDITOR for more complex modification; command line editing mostly makes this unnecessary, but there are some edits that are hard to do on the command line.

You can also do fairly complex manipulation using ! history reference syntax, but for historical reasons (the basic history mechanism was established by early csh and all enhancements have mostly kept compatibility) it uses a different syntax. See here for details.

link|improve this answer
Wasn't aware of the 'r' command. Thanks! – Bubnoff Mar 9 '11 at 3:00
1  
r is an alias which probably needs to be defined (some installations may include it by default in .bashrc). fc still only does string substitutions (it doesn't support wildcards). – Dennis Williamson Mar 9 '11 at 3:24
1  
It will also depend on bash version; r was inherited from ksh, and bash 4 seems to be removing all the ksh-isms. – geekosaur Mar 9 '11 at 3:42
feedback
$ ssh foo@bar.org
...
$ ^foo^gary^
...

The command is repeated using "gary" as the username instead of "foo". The following works the same way:

$ ssh foo@bar.org
...
$ !!:s/foo/gary/
...
link|improve this answer
I was aware of these methods. But depending on the strings, wildcards would be much quicker. How much regex support is there for examples like your second? – Bubnoff Mar 9 '11 at 2:47
The last caret is unnecessary in example one – Bubnoff Mar 9 '11 at 2:48
1  
@Bubnoff: Unfortunately, Bash history substitution doesn't support wildcards. Zsh, however, does. – Dennis Williamson Mar 9 '11 at 3:01
@Bubnoff: The last slash is also unnecessary in the second example. – Dennis Williamson Mar 9 '11 at 3:02
Thanks Dennis! Definitely a point in Zsh's favor. – Bubnoff Mar 9 '11 at 4:14
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.