97

Is there a better way to search my history file for a command than grep? I do have some idea what the command starts as, but I don't know how far back in the history it is.

update: was formerly zsh specific but due to overlapping answers feel free to answer for any shell (or mode (vi/emacs)) here, just note if it is specific.

xenoterracide
  • 59,188
  • 74
  • 187
  • 252

15 Answers15

89

Ctrl+R is usually the best way, as descriptor said. You can also use !string, which runs the most recent command starting with string, or !?string?, which runs the most recent command that contains string.

(I think that's the only stuff relevant to this question, but I covered much more of the history commands in this answer)

Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
36

When using Bash, type Control-R and then start typing. Typing Control-R repeatedly after inputting some text will move you back in matching command lines.

bignose
  • 480
grendel
  • 491
  • 3
  • 3
20

Not sure if this will help, but I like to use ctrl-r and then start typing the command. It should go through your history and present you with the first match. To toggle through the matches just hit ctrl-r again.

bignose
  • 480
decriptor
  • 433
  • 2
    Sorry, forgot about the zsh. You might have to add this keybinding to your ~/.zshrc:

    bindkey '^R' history-incremental-search-backward

    – decriptor Aug 16 '10 at 19:49
18

If you add the following to ~/.inputrc

"\e[5~": history-search-backward
"\e[6~": history-search-forward

and restart Bash, you can start typing, and then use Page Up and Page Down to move backward and forward through the history of lines starting with the same prefix you just typed.

(Some may prefer to use \e[A and \e[B, which will replace the normal Up and Down actions instead of binding new keys.)

ephemient
  • 15,880
  • I prefer to map these commands to Alt + Up and Alt + Down. Depending on the keyboard emulation the terminal emulate uses these combinations might be mapped either to \E[A and \E[A (e.g. KDE Konsole with Linux Key Bindings) or \E[1;3A and \E[1;3B (e.g. XFCE Terminal or KDE Konsole with X Free 4 Bindings). – Christian Herenz Sep 22 '19 at 12:19
  • do you know why some commands may break this in bash? – dashesy Apr 19 '20 at 03:12
9

The interactive prompt invoked by Ctrl-R, which had been already mentioned, is the most convenient way. Additionally it's popular to remap Up and Down arrow keys to search the history for a prefix currently on the command line, however this requires some changes to the ~/.inputrc file.

The classic and less interactive solution is to use shell history expansion. Typing

!foo

will execute the last command that starts with foo and

!?foo

will execute the last command that contains foo. More information about history expansion can be found in the Bash reference manual, assuming your shell is Bash or compatible.

bignose
  • 480
Adam Byrtek
  • 1,339
8

If you add stty -ixon to your ~/.bashrc file then Ctrl-s will go in the opposite direction to Ctrl-r.

  • I wanted to use C-s for this purpose, but my terminal got frozen; beware! (Well, I haven't yet employed any stty ixon, not sure what this is for.) – imz -- Ivan Zakharyaschev Apr 27 '11 at 12:26
  • 5
    @imz: C-q will "unfreeze". It and C-s are the usual software flow control characters which were once useful to manually interrupt (pause) the flow of output when slow serial connections were used. Now output is so fast in most cases that what you want to see when you press C-s has already scrolled by. stty -ixon turns off software flow control. – Dennis Williamson Apr 28 '11 at 11:19
  • Fantastic! I have searched for years for a way to scroll forward in history like this. – marlar Dec 31 '16 at 09:11
7

I'm surprised this hasn't been mentioned - but you can select vi-mode in bash or ksh by doing this:

set -o vi

...or using this as the contents of ~/.inputrc (for GNU readline used in programs such as bash):

set editing-mode vi

Then after that, you can use Esc to enter command mode and use k to go back in history, and j to go forward. You can also search using / to search normally, and ? to search in reverse.

If you use ~/.inputrc, then this will work not just in GNU bash but in anything that uses GNU readline such as CLISP and possibly programs like the MySQL command shell and like the CPAN shell.

Mei
  • 1,136
3

If you type !ls then bash will look through your history and execute the most recent command that begins with "ls"

Kevin M
  • 1,973
3

To switch forward when using reverse search (with Ctrl+R command) :

  1. Open your .bashrc file :
    sudo gedit ~/.bashrc

  2. Add this line (the letter f can be replaced with another not yet used by the system)

    bind '"\C-f": forward-search-history' 
    
  3. Close your file and update your ~/.bashrc (or open another terminal) with the command:
    source ~/.bashrc or . ~/.bashrc

Now you can move forward in the history with the shortcut: Ctrl+F

Working on Ubuntu 18.04 LTS

3

I use following two most of the time.
But please note both of them search for starting chars.

  1. tcsh: type some few charecters of the command then Esc+p it will show the previous command starting with that key sequence press it again it will show another command.
  2. ksh : use fc -e - <SPACE> <first few char for your previous > this will run last command matching that sequence.

I was not able to find something like Ctrl+R in Bash for my ksh and tcsh.

bignose
  • 480
Hemant
  • 6,910
  • 5
  • 39
  • 42
  • 3
    Ctrl+r works a little differently in ksh than Bash. Press Ctrl+r then type the string you're looking for and press enter. To search for the same thing, press Ctrl+r and enter without having to re-type the string. This is in set -o emacs mode, by the way. – Dennis Williamson Aug 17 '10 at 19:32
  • @Dennis: +1 :-) – Hemant Aug 18 '10 at 05:18
2

might be zsh specific. In researching this answer I found vi-history-search-backward which allows one to search with / in vi mode (which I didn't mention I was in) you can then use n and N to search forward and backward respectively (after pressing enter).

xenoterracide
  • 59,188
  • 74
  • 187
  • 252
2

I find fzf works better for this task, which supports fuzzy-search your command history. To install fzf, run the following command:

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
# say yes to its install prompts
~/.fzf/install

Restart the shell, you should get a far better experience searching your history commands (the shortcut is still Ctrl+R). To navigate the search results, use Ctrl+N and Ctrl+P.

jdhao
  • 606
  • Wow, this is much more feature-rich than all the other answers here (with the possible exception of vi-history-search-backward which I didn't try 'cause I'm an emacs guy) – ijoseph Jun 08 '22 at 20:08
1

There is a way to use Ctrl-R with tcsh. Add the following in your ~/.cshrc:

bindkey "^r" i-search-back (it is just a caret sign and the letter r)

That's the biggest time saver for me.

bignose
  • 480
1

similar answer to @ephemient, but you can put into your .bashrc

bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-foward'

and type part of the phrase, and then use the up/down arrow to browse the most recent options that match. This is matlab's default behavior.

For most folks, if you want to port your settings to a new system, it is easier to remember to snag just your ~/.bashrc then that that you have to snag that ~/.inputrc

Matt S.
  • 181
0

Yes it exists, at least if you are using zsh. Just start typing the command and then press M-p (ESC p) and it will find previous commands that matches what you typed. Press it again to find the next match.

dkagedal
  • 776