This is the fourth part of the Bash One-Liners Explained article series. In this part I'll teach you how to work with bash history. I'll use only the best bash practices, various bash idioms and tricks. I want to illustrate how to get various tasks done with just bash built-in commands and bash programming language constructs.

I'll break this part into several sub-parts as it's very tiring to write long articles, and I'd rather publish many short articles and make quick progress.

See the first part of the series for introduction. After I'm done with the series I'll release an ebook (similar to my ebooks on awk, sed, and perl), and also bash1line.txt (similar to my perl1line.txt).

Also see my other articles about working fast in bash from 2007 and 2008:

Part IV: Working with history

Bash keeps the shell history in a hidden file called .bash_history. This file is located in your home directory. To get rid of the history, just delete it.

Note that if you logout after erasing the shell history, this last rm ~/.bash_history command will be logged. If you want to hide that you erased shell history, see the next one-liner.

2. Stop logging history for this session

$ unset HISTFILE

The HISTFILE special bash variable points to the file where the shell history should be saved. If you unset it, bash won't save the history.

Alternatively you can point it to /dev/null,

$ HISTFILE=/dev/null

3. Don't log the current command to history

Just start the command with an extra space:

$ command

If the command starts with an extra space, it's not logged to history.

Note that this only works if the HISTIGNORE variable is properly configured. This variable contains : separated values of command prefixes that shouldn't be logged.

For example to ignore spaces set it to this:

HISTIGNORE="[ ]*"

My HISTIGNORE looks like this:

HISTIGNORE="&:[ ]*"

The ampersand has a special meaning - don't log repeated commands.

4. Change the file where bash logs command history

$ HISTFILE=~/docs/shell_history.txt

Here we simply change the HISTFILE special bash variable and point it to ~/docs/shell_history.txt. From now on bash will save the command history in that file.

5. Add timestamps to history log

$ HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S"

If you set the HISTTIMEFORMAT special bash variable to a valid date format (see man 3 strftime) then bash will log the timestamps to the history log. It will also display them when you call the history command (see the next one-liner).

6. Show the history

$ history

The history command displays the history list with line numbers. If HISTTIMEFORMAT is set, it also displays the timestamps.

7. Show the last 50 commands from the history

$ history 50

If you specify a numeric argument, such as 50, to history, it prints the last 50 commands from the history.

1. It looks weird, that you are taking the second column of history output with cut, instead of doing that inside of awk block. (in your "top 10" example)

2. I think that awk is an overkill for the common task of counting the number of entries. The same can be done a la "| sort | uniq -c | sort -nr". I think that this code snippet is much easier to remember than the line of awk code, even though it performs worse.

Checkout Bash "inputrc", which controls the behavior of readline. You can do some really cool things (capture command in a visual editor, modify it, return it to the command line for execution). As I was reading the above, I kept echoing one variable at a time. I used parameter expansion:
for p in "${!HIST@}"; do echo $p=${!p}; done