118

I recently switched from bash to zsh. In bash, one way (besides recursive search) that I used to find previously-run commands was history | grep whatever, where whatever is the bit of command I remember.

In zsh, this isn't working. history returns only a few items, even though my .zsh_history file contains many entries, which I have configured it to do.

How can I output my whole history, suitable for searching with grep?

Nathan Long
  • 26,015
  • 36
  • 102
  • 139

3 Answers3

163

History accepts a range in zsh entries as [first] [last] arguments, so to get them all run history 0.

To get the zsh help (at least with mind) type Alt-h over the history command and this will bring up the help for built-ins.

Kyle Brandt
  • 4,429
  • 4
  • 36
  • 37
43

The accepted answer is correct, but it’s worth noting that you don’t need to call the external grep binary to do the search, since that ability is baked in. I have this function defined in my .zshrc:

histsearch() { fc -lim "*$@*" 1 }

Notes:

  • fc is the zsh builtin that controls the interactive history. history is equivalent to fc -l.

  • The -m flag requires a pattern, which must be quoted.

  • The -i flag adds a timestamp.

  • fc has many more tricks up its sleeve (e.g. limiting the search to internal history for the current session). See the zshbuiltins(1) man page or the official documentation.

Edit (2021-01-27):

A major advantage of using this method over just grepping the zsh history file is you get human-readable timestamps via -i. Of course, this only works if you’ve enabled the saving of timestamps to the history file in the first place:

setopt EXTENDED_HISTORY

Over the years, I’ve also added the -D flag to my function, which shows the runtime of the command in history. (This is again dependent on EXTENDED_HISTORY.) Plus, I’ve renamed the function to hgrep, which I find easier to remember:

hgrep () { fc -Dlim "*$@*" 1 }
wjv
  • 1,081
  • 10
  • 14
  • 3
    Better yet is to use "\*$@\*" (note additional stars) pattern instead of "$@" as the latter yields only exact matches. – Piotr Dobrogost May 07 '18 at 11:50
  • 2
    You’re completely right, @PiotrDobrogost! I’m not sure how I managed to submit this answer in the state that I did — I’m guessing I must’ve typed that function from memory. As it stands it’s not very usable, so I’m going to edit the answer to incorporate the asterisks. – wjv May 07 '18 at 13:15
  • 1
    I just switched to zsh from bash, this helped me out. I wished I had this tip years ago. All that time I've been foolishly using grep. – Halfstop Apr 24 '20 at 13:53
  • Using grep is certainly not "foolish", @Halfstop. In fact, I would say it's the obvious thing to do, and probably how most people would accomplish this task daily. My answer is more of a "zsh insider alternative". (But it turns out that it does have certain advantages, as I pointed out in the edit I made to the answer in January this year.) – wjv Apr 06 '21 at 08:04
  • The 2nd quote in the last command is probably a typo. – Teddy C Sep 09 '21 at 07:01
  • @TeddyC Yeah I have no idea how that crept in. Fixed; thanks for pointing it out. – wjv Sep 10 '21 at 09:13
  • if you’re calling it `hgrep`, wouldn't it be better to write it something like `hgrep() { fc -Dli 1 | grep $@ }`? EDIT: I tried this and it’s quite slow, compared to other methods. Must be decoding -Di before feeding to grep. – Rick Jul 04 '23 at 22:53
7

Have a look at fzf. It helps not only finding "whatever-particles" in your shell history, but also in other interesting places, e.g. browser history, directory history, etc.

fzf is a command-line fuzzy finder. That means you can search for particles or fractions of what you are looking for and it will display a collection of matches which you can continuously refine. It's really a game changer.

The homepage of the author contains a number of illustrative examples.

  • Consider adding some reference to this answer supporting what you state. – Vomit IT - Chunky Mess Style Oct 09 '17 at 22:44
  • Welcome to Super User! Please read [How to recommend software](https://meta.superuser.com/a/5330/213131) for **minimum required information** and suggestions on how to recommend software on Super User. To keep your answer useful even if the provided link(s) breaks these details should be edited into your answer. – I say Reinstate Monica Oct 09 '17 at 23:31