## 30.7. History by Number

Most of the history examples we've shown use the first few letters in a command's name: `!em` to repeat the previous Emacs command, for example. But you also can recall previous commands by their numbered position in the history list. That's useful when you have several command lines that start with the same command. It's also more useful than interactive command-line editing (Section 30.14) when you'd like to see a lot of previous commands at once and then choose one of them by number.

To list previous commands, use the history command. For instance, in bash and the C shells, history 20 shows your last 20 commands. In zsh and the Korn shell, use a hyphen before the number: history -20 (also see the discussion of fc, later in this article). Here's an example:

>     $ history 8
>      15  show last +upt/authors
>      16  vi ../todo
>      17  co -l 0444.sgm
>      18  vi 0444.sgm
>      19  ci -u 0444.sgm
>      20  rcsdiff -u3.4 0444.sgm > /tmp/0444-diff.txt
>      21  scp /tmp/0444-diff.txt webhost:adir/11.03-diff.txt
>      22  getmail;ndown
>     $ rm !20:$
>     rm /tmp/0444-diff.txt
>     $ !16
>     vi ../todo

The number at the start of each line is the history number. So, to remove the temporary file I created in command 20 (the name of which I'd already forgotten!), I can use !20:$ (Section 30.8) to pass that filename as an argument to rm. And to repeat command 16 (vi ../todo), I can type `!16`.

This sort of thing is often faster than using arrow keys and editor commands to recall and edit previous commands. It lets me see several commands all at once, which makes it easier to spot the one(s) I want and to remember what I was doing as I worked. I use it so often that I've got a set of aliases that list bigger and bigger chunks of previous commands and an alias that searches history, giving me a chunk of matching command lines. Here they are in C shell syntax:

`less` Section 12.3, `\!*` Section 29.3

>     alias h     history 5     # show last five lines
>     alias hi    history 10    # show last ten lines
>     alias his   history 20    # show last 20 lines
>     alias hist  'history 40 | less'        # show last 40; pipe to 'less'
>     alias histo 'history 70 | less'        # show last 70; pipe to 'less'
>     alias H     'history -r | fgrep "\!*"' # find something in history

The history -r option shows the list in reverse order: most recent first. If you don't give a count of lines to list, you'll see all of them.

> WARNING: Be careful! In bash, history -r reads the current history file and uses it as the history from that point onward, trashing any current history for that shell if it has not yet been written to the history file (defined in the environment variable HISTFILE).

To avoid typing the history command, you can include the history number in your prompt (Section 4.3). Then you can repeat a recent command by glancing up your screen to find the command number from its prompt.

There's another way to see a list of your previous commands in bash, ksh, and zsh: the command fc -l (lowercase L, for "list"). (In ksh, the command history is actually just an alias that executes fc -l.) By itself, fc -l lists the previous 16 commands:

>     $ fc -l
>        ...
>     19      ls -F
>     20      less expn.c
>     21      vi expn.c
>     22      make
>     23      expn info@oreilly.com
>     24      fc -l

For an even shorter list, give fc the first number or name you want to list. For instance, `fc -l vi` or `fc -l 21` would give the last four lines above. You can also use a second argument that ends the range before the current line. If you type `fc -l vi expn` or `fc -l 21 23`, you'll see commands 21 through 23.

tcsh and zsh automatically keep timestamps with their history. The tcsh command history shows the time of day by default. In zsh, you can see this info with the options -d, which shows the times, -f, which shows both dates and times, and -D, which shows elapsed times. For example, the scp command started running at 12:23 (PM) and took 1 minute 29 seconds to run:

>     % fc -l -f -4
>      1003  10/23/2000 12:23  nup
>      1004  10/23/2000 12:23  scp ../upt3_changes.html webhost:adir/.
>      1005  10/23/2000 12:25  less /etc/hosts
>      1006  10/23/2000 12:25  getmail;ndown
>     % fc -l -D -5
>      1003  0:29  nup
>      1004  1:29  scp ../upt3_changes.html webhost:adir/.
>      1005  0:05  less /etc/hosts
>      1006  0:21  getmail;ndown
>      1007  0:00  fc -l -f -4

zsh also has several related options for fc that allow for the history to be written out to a file, read in from a file, et cetera. The other shells allow for even more extended functionality. In bash, for example, fc -e with appropriate options will start an editor (defined by the FCEDIT environment variable) and load up a new file containing the recent history items. Think of it is jump starting a script from a sequence of (hopefully) successfully executed commands. See the other shells' manual pages for more details.

--JP and SJC

Copyright © 2003 O'Reilly & Associates. All rights reserved.