How to remove an entry from the history in ZSH

Zsh

Zsh Problem Overview


Let's say I ran a command using a zsh

echo "mysecret" > file

I can easily print the history including the entry numbers using the command fc -l:

> 1 echo "mysecret" >| file

But how can I easily delete an entry from the history?

I cannot find a corresponding paragraph in man zshbuiltins.

Zsh Solutions


Solution 1 - Zsh

*BSD/Darwin (macOS):
LC_ALL=C sed -i '' '/porn/d' $HISTFILE
Linux (GNU sed):
LC_ALL=C sed -i '/porn/d' $HISTFILE

This will remove all lines matching "porn" from your $HISTFILE.

With setopt HIST_IGNORE_SPACE, you can prepend the above command with a space character to prevent it from being written to $HISTFILE.

As Tim pointed out in his comment below, the prefix LC_ALL=C prevents 'illegal byte sequence' failure.

Solution 2 - Zsh

I don't know if there is some elegant method for doing this, but in similar situations I have logged out (allowing zsh to empty its buffer and write my history to file), then logged in, and finally manually edited ~/.zsh_history, deleting the "dangerous" line.

Solution 3 - Zsh

If you use the HIST_IGNORE_SPACE option in zsh you can prepend commands with a space " " and they will not be remembered in the history file. If you have secret commands you commonly use you can do something along the lines of: alias hiddencommand=' hiddencommand'.

Solution 4 - Zsh

I think the solution I found is easier.

In a zsh terminal (in mac os)

  1. I closed the terminal session in which I had a command I wanted to delete.
  2. Opened a new session,
  3. opened ~/.zsh_history with a text editor (I used emacs but nano or any other would do, I guess),
  4. deleted the faulty lines, closed the editor,
  5. closed the Terminal session,
  6. opened a new Terminal sessionsession,
  7. entered history and the unwanted history item was gone.

Make sure emacs hasn't backed up the previous .zsh_history instance.

(Solution based on https://til.hashrocket.com/posts/zn87awopb4-delete-a-command-from-zsh-history-)

Solution 5 - Zsh

This function will remove any one line you want from your Zsh history, no questions asked:

# Accepts one history line number as argument.
# Alternatively, you can do `dc -1` to remove the last line.
dc () {
  # Prevent the specified history line from being saved.
  local HISTORY_IGNORE="${(b)$(fc -ln $1 $1)}"

  # Write out the history to file, excluding lines that match `$HISTORY_IGNORE`.
  fc -W

  # Dispose of the current history and read the new history from file.
  fc -p $HISTFILE $HISTSIZE $SAVEHIST

  # TA-DA!
  print "Deleted '$HISTORY_IGNORE' from history."
}

If you want to additionally prevent all dc commands from being written to history, add the following in your ~/.zshrc file:

zshaddhistory() {
 [[ $1 != 'dc '* ]]
}

Update

I've now published a more comprehensive solution as a plugin: https://github.com/marlonrichert/zsh-hist

Solution 6 - Zsh

In BASH [Not ZSH]:

1- in bash terminal type

hsitory # This will list all commands in history .bash_history file with line numbers

ex:

  ...
  987  cd
  988  ssh [email protected]
  990  exit
  991  cd

2- pick the CMD line number you want to delete

history -d 988

Note: if you want to delete for example last 3 CMDs, just pick the third line number from bottom ex: 988 and repeat the CMD history -d 988 3 times in sequence.

Source

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsandozView Question on Stackoverflow
Solution 1 - ZshrxwView Answer on Stackoverflow
Solution 2 - ZshpopliteaView Answer on Stackoverflow
Solution 3 - ZshMichael BartonView Answer on Stackoverflow
Solution 4 - ZshpilgixView Answer on Stackoverflow
Solution 5 - ZshMarlon RichertView Answer on Stackoverflow
Solution 6 - ZshKhogaEslamView Answer on Stackoverflow