views:

424

answers:

5

Scenario:

You are doing your daily Bash shell stuff. You want to run a previous command so you type:

history | grep foocommand

Then you get a list of all the foocommand stuff you did for however long your history has kept track, in a list like so:

  585 foocommand --baz --bleet
  750 foocommand | grep quux
  987 history grep | foocommand

You decide you want to run command 585, so you type

  !585

Question: Just for curiosity, is there a way to take that final step out of the equation and still get the expected outcome? It would be nice if there were a way to say:

 "grep through history and automatically run the first item on the list"

or

"grep through history and let me choose which item to run using the arrow keys"
+3  A: 

Did you try '!f'? 'f' as first letter of the foocommand.

Mykola Golubyev
+4  A: 

Press ^r (that's CTLR-r), type foocommand press Enter ;) That will search history and show the latest matching entry

Tomasz Tybulewicz
"To Start Press Any Key". Where's the ANY key? I see Esk ["ESC"], Catarl ["CTRL"], and Pig-Up ["PGUP"].
eleven81
It depends on keys mode. It won't work on the 'vi' mode.
Mykola Golubyev
+1, gotta love readline :)
Tim Post
A: 

The syntax

!foo

will run the last command that began with foo.

Failing that, bash uses the readline library for input, which supports the history-search-forward and history-search-backward commands that can be bound to keys of your choice. I've edited my ./inputrc file to bind them to F8 and Shift-F8, so that they work like Windows' equivalent feature in the console when I connect with PuTTY:

"\e[19~":history-search-backward
"\e[32~":history-search-forward
j_random_hacker
A: 

"grep through history and automatically run the first item on the list"

Okay.

`history | grep foocommand | head -1 | tr -s ' ' | cut -d ' ' -f 3-`

Give it a try, it works like a champ!

eleven81
A: 

Personally, I use an alias derived from ksh:

alias r="fc -e -"

('r' for 'rerun', I suppose...)

I can rerun the last command starting with 'foo':

r foo

I can rerun commands 46 to 50:

r 46 50

I can rerun just command 585:

r 585

The only gotcha is that if you typed:

$  cd somewhere

then running 'r cd' won't work because there was an extra space in front of the 'cd' command. The 'fc' command underlies history, and you can edit commands 46 to 50 before rerunning them by typing:

fc 46 50

and so on for the other variants.

(The '-e -' in the alias means 'edit with the null editor'; you could write 'fc -e vim' to edit with vim, but most people set VISUAL or EDITOR or FCEDIT or all three to make that unnecessary.)

For the rest, being a 'vim' person (fanatic?), I use 'set -o vim' and then the search facility: ESC and

/grep\ -e\ 'whatever

to search history for a command containing "grep -e 'whatever". I can repeat the search, moving ever further backwards in history, or reverse direction after overshooting, or ... I assume that the emacs mode has an equivalent search mechanism.

Jonathan Leffler