Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

How can I remove a certain line from history's database?

share|improve this question
9  
Please don't write "Thanks" comments all over the place. Upvote answers you find helpful and accept the ones that helped you most. This is the way to say thanks here. –  slhck Jan 31 '12 at 16:33
add comment

9 Answers

up vote 25 down vote accepted

Just edit the file ~/.bash_history.

share|improve this answer
5  
If the HISTFILE environment variable is set, the history file isn't ~/.bash_history but rather ${HISTFILE}. –  Karolos Apr 3 '13 at 22:34
1  
Entries are written into the history file when you exit the shell. Therefore, after entering a command that you'd like to remove, you need to either log out and back in, or use 'history -d xxxx' to remove them from the current shell session. –  harmic Jan 24 at 0:19
add comment

Typing "history -d xxx" will delete a specified line. You then have to type "history -w" to make them permanent. It also removes them from the .bash_history file. The surest fire way is cYrus's answer.

share|improve this answer
add comment

To prevent a command from being added to the history in the first place, make sure that the environment variable HISTCONTROL contains among its colon-separated values the value ignorespace, for example (add e.g. to .bashrc):

$ export HISTCONTROL=ignorespace

This will prevent any command with a leading space from being added to the history. You can then clear the history completely by running

$  history -c -w
  ^-- additional space character
share|improve this answer
    
Wow, that is amazing. Never have tried/heard of this option –  w0rldart Feb 1 '12 at 23:25
add comment

If you need to remove several lines at the same time I normally use this:

history | grep <string> | cut -d ' ' -f 3 | awk '{print "history -d " $1}'

If you need to remove the last command you can use:

history -d $((HISTCMD-2))
share|improve this answer
    
This looked like it worked but history | grep <string> still shows all the lines it claimed to delete... –  Brock Hensley Apr 19 '13 at 0:09
    
This will delete the wrong history lines after deleting the fisrt!! –  mivk Dec 20 '13 at 14:51
    
But fortunately, it only prints the wrong delete commands. The following would print the correct delete commands: history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}' –  mivk Dec 20 '13 at 15:17
add comment
history | sed -i 59d

59 is the line number. Cannot be anything sweeter than this :)

share|improve this answer
add comment

First of all, if the command you're about to issue is sensitive, unsafe, or you just don't need it cluttering up your history, it is best/quickest to just prevent it from entering the history in the first place. Make sure that $HISTCONTROL contains ignorespace:

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

Then proceed any command you don't want in your history with a space:

(bash)$  sensitive-cmd-with --password 82cf7dfe
(bash)$  rm -r... # One-off recursive remove; mustn't be accidentally repeated!

If you accidentally put an unwanted command into history, providing that your bash session is still open, the command hasn't yet touched the disk. To delete the previous command in history, issue:

(bash)$  history -d $((HISTCMD-1))

Note the leading space; this command requires ignorespace, otherwise it'll just delete itself!

If you want to delete the last few commands, find the last and first history number:

(bash)$  history 5
  598  ok
  599  sensitive
  600  unsafe
  601  doesn\'t-work
  602  otherwise-unwanted

In this case 602 and 599. Then issue:

(bash)$  for i in {602..599}; do history -d $i; done

(Without ignorespace, it would be 603..599.)

If you don't want any history from your current session to hit the disk, exit using:

(bash)$ kill -9 $$

The approach so far is to not even let sensitive history items be written to disk for extra security, because in theory data deleted from non-volatile media can still be recovered.

If, however, the command(s) you wish to remove are from a previous session, they will have already been appended to the $HISTFILE on exit. Manipulating the history with the above commands will still only append the remaining new items to the $HISTFILE, on exit. To overwrite the $HISTFILE with the current session's view of the entire history, right now, issue:

(bash)$  history -w

Of course for history items already on disk, the alternative to editing the history with history -d commands then issuing history -w, is to edit the $HISTFILE with a text editor.

share|improve this answer
    
wow... really nice and extense explanation. Thank you –  w0rldart Jun 18 '13 at 17:01
1  
”Manipulating the history with the above commands will still only append the remaining new items to the $HISTFILE, on exit.” Actually, this isn't exactly true. It seems to only append remaining new items that ‘stick out’ from the original history length. E.g. If I remove 5 original items and add 15 new, only the last 10 new are appended, whereas I'd expect all 15 new to be appended. I think this is a bug because I can't see how this is ever desirable functionality. –  James Haigh Jun 19 '13 at 15:59
1  
I guess bash takes note of the original length. On session close, it presumably appends items whose number is greater than this value. If this value was decremented every time an item is deleted whose number is less than or equal to this value, it would work as expected. ;-) –  James Haigh Jun 19 '13 at 16:06
add comment

Prevent sensible information from being stored in history file

If you've hitted some password on command line, than realize that all commands are logged, you could either:

  1. Force exit current session without saving history:

     kill -9 $$
    

    This will drop all current history.

  2. Hit on oppened bash session Up until sensible informations are shown, than Ctrl+w until sensible infos are deleted than down until new empty line is prompted, before enter.

Delete sensible information from history file

If you realize that sensible informations is already stored, you want delete them, but not whole history.

Simple sed command could do the job:

sed -e '/SeNsIbLe InFoS/d' -i .bash_history

but, as you write this, you create another history line with info you try to delete... So you could:

sed -e "/$(head -n1)/d" -i .bash_history

This will stay locked until you hit sensible info on terminal, than use our entry to delete from .bash_history all lines containing sensible infos.

Another way could be to drop only sensible infos, but keep commands anyway. For this, you could simply replace sensible infos by a pattern of your choice:

sed -e "s/$(head -n1)/Santa Claus/g" -i .bash_history.

Delete sensible information from any file in a specific tree

Finally, to be sure that this won't stay in another forgotten file:

SENSIBLEINFO="$(head -n1)"
find . -type f -print0 | xargs -0 grep -l "$SENSIBLEINFO"

will list all concerned files.

find . -type f -print0 |
    xargs -0 grep -l "$SENSIBLEINFO" |
    tr \\n \\0 |
    xargs -0 sed -e "s/$SENSIBLEINFO/Santa Claus/g" -i

will replace all occurence of sensible infos in all files in directory ..

share|improve this answer
    
wow... great extensive info, and nice trick with ctrl+w, as I didn't know about it, till now –  w0rldart Jul 19 '13 at 13:11
add comment

If you need to remove a range of lines from history, the following bash function could save you some time:

function histdel() {
    [ $# -eq 1 ] && history -d "$1" && history -w
    if [ $# -eq 2 -a "$1" -le "$2" ]; then
        for n in `seq "$2" "$1"`; do
            history -d "$n"
        done
        history -w
    fi
}

Function should be typically added to $HOME/.bashrc. To use the function imediatelly, you will need to have the file read again by your running shell (. $HOME/.bashrc). Then to delete e.g. commands 200-210 from history:

$ histdel 200 210

(Note: This question is among the top search results if you search for deleting a range of commands from bash history. So, while the above is more than what the question asks, it could be useful for some readers.)

share|improve this answer
2  
Alternative forms for the for statement: for n in $(seq "$2" "$1") is stylistically preferred by some, and, if seq doesn’t work, try for ((n="$2"; n>="$1"; n--)). –  Scott Mar 13 '13 at 18:11
add comment

Just try these,

$ history

this will display the id of the history and the command, e.g.

.
.
211 ls
212 javac Welcome.java
213 java welcome
.
.

use,

$ history -d 211

Here 211 is the id of the history. Now check this using

$ history

.
.
211 javac Welcome.java
212 java welcome
.
.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.