如何从Bash历史记录中删除选定的结果?

history 命令可以显示所有结果,但我们可以使用 history | grep searchingCommand 来筛选获取特定的命令。这真的很有帮助。

但问题是它还会显示那些输入错误或无效的命令。然后要找到正确的命令就很麻烦。我查看了这个链接:终端中选择性的命令历史记录? 但那不是我的解决方案。

所以,有没有办法从历史记录中删除那些在输入时或之后是错误的命令呢?


6请修改已接受的答案,还有其他回答获得了100个以上的赞同票。 - greuze
1@greuze:已更改为最佳答案。票数多并不意味着它就是最好的! - Saurav Kumar
7个回答

使用:

history -d OFFSET

即使在将历史记录条目添加到您的bash历史文件之前,也可以删除偏移量为OFFSET的历史记录条目。要找到正确的OFFSET,您只需要运行history命令。这是包含您想要删除的历史记录条目的行的起始处的数字。

要保存对历史记录的修改,请使用:

history -w

本指南中查看更多详细信息。

不错:) 开启新的方式挺好的。 - Saurav Kumar
10@SauravKumar 不错吧?可能是最好的方式... - Radu Rădeanu
@Radu Rădeanu 这是一种欺骗的方式。当我关闭终端并再次打开时,历史记录并没有被删除。对这个回答给予负1分。 - αғsнιη
5首先要明确的是,你必须在完成操作后执行history -w命令来保存更改。另外,OFFSET表示history显示的行号。如果你想删除的行号是873,那么请使用history -d 873命令。 - cubecubed
2@RaduRădeanu 在执行history -d命令后,使用history -w来保存更改。 - cubecubed
如何从历史记录中删除最后一个 history -w - Midhun KM
20这应该是正确的答案。 - topher
OFFSET是在运行history命令时看到的命令编号。所以,如果你运行history | tail并且看到了10个命令,倒数第二个命令是569 ./shouldnt_be_in_history -p password,那么你只需运行history -d 569来删除它。 - s g

编辑文件~/.bash_history并删除有错别字的命令。
例如,插入以下命令:
gedit ~/.bash_history

编辑你喜欢的内容,然后保存文件并重新启动终端。 根命令如下:
sudo -i 
inser your password
gedit ~/.bash_history

如果你想删除所有的历史记录,可以使用history -c命令来完成。

SYNTAX

history
history [n]
history -c
history -d offset
history [-anrw] [filename]
history -ps arg

KEY

-c Clear the history list. This may be combined with the other options to replace the history list completely.

-d offset Delete the history entry at position offset. offset should be specified as it appears when the history is displayed.

-a Append the new history lines (history lines entered since the beginning of the current Bash session) to the history file.

-n Append the history lines not already read from the history file to the current history list. These are lines appended to the history file since the beginning of the current Bash session.

-r Read the current history file and append its contents to the history list.

-w Write out the current history to the history file.

-p Perform history substitution on the args and display the result on the standard output, without storing the results in the history list.

-s The args are added to the end of the history list as a single entry.

来源:


谢谢,这很有帮助!你知道怎么在命令行输入时删除条目吗?或者有没有不打开.bash_history的命令来删除条目? - Saurav Kumar
1@bladed19899 history -c 不起作用。当我关闭终端并重新打开时,历史记录并没有被删除。对于你的回答给出-1评分。 - αғsнιη
1@KasiyA,-c 清除历史记录列表。可以与其他选项结合使用,完全替换历史记录列表。 来源 - blade19899
2@KasiyA 在执行 history -c 后使用 history -w 命令来保存更改。 - cubecubed

警告(03/05/23):

我在原始回答中描述的方法并不真正安全。请向本文底部滚动以了解更多信息。


(原帖)

我想要增加另一种修改(或删除)历史记录条目的方法,这是我在使用bash时偶然发现的:

为了证明这一点,请在bash中执行以下三个命令:

$ echo 1
1
$ echo 2
2
$ echo 3
3

你可以使用箭头键或Ctrl+pCtrl+n再次选择这些命令。
假设你想修改前两个命令。在历史记录中移动直到出现echo 1,然后将其更改为echo 1 - changed,但不要按回车键。如果你继续移动历史记录,这一行将保持修改后的状态,并且你可以离开它然后返回。现在移动到echo 2这一行,将其更改为echo 2 - changed,同样不要按回车键。为了保存对这些行的更改,选择除了这两行之外的任何命令,并按下Ctrl+c
当然,你也可以删除历史记录条目,这将导致该条目处显示为空行。要删除当前显示在提示符处的行,请按下Ctrl+e(跳转到行尾),然后再按下Ctrl+u(删除从行首到光标处的文本)。
请参阅https://unix.stackexchange.com/questions/195668/what-can-cause-an-item-to-be-deleted-from-my-bash-history/195726#195726,以获取有关技术背景的更详细解释。

(由Saurav Kumar于02/06/2018添加)

最简单的方法:

  1. ctrl+r搜索要删除/修改的命令。
  2. end选择要删除/修改的搜索命令
  3. 删除或修改所选命令(不要按enterctrl+c
  4. 上箭头(或ctrl+p)或下箭头(或ctrl+n)选择其他命令。
  5. ctrl+c 就是这样!

注意:

这只会更改当前会话的命令。如果我们想要更改旧的命令并保存更改,需要在关闭终端之前运行以下命令:

history -w

(于2023年03月05日添加)

假设你刚刚以错误的方式输入并执行了一个命令,而你想要更改或删除历史记录中的错误行。那么你可能会去到那一行并进行更改(就像修正拼写错误一样),使其包含正确的命令,然后按下Ctrl+c,这样正确的命令就保存在那一行上了。然而,如果你现在去执行那一行,旧的行将重新出现在原来的位置。

解决这个问题的一个方法是:前往错误的行并进行更正,然后按下Alt+#。这将把正确的命令作为注释附加到当前的历史记录列表中。现在你可以按照上述描述的方式删除错误的行。之后,你可以通过按下HomeDel(或Ctrl+pCtrl+aCtrl+d)来执行修正后的命令。

警告:在执行删除命令时,务必避免按下或关闭终端,否则该命令将被保存到历史文件中。消除此风险的一种方法是使用

 history -d -2

(请注意命令开头的前导空格)不要按照原始答案中描述的方式删除错误行,而是使用 -2 选项。如果您在执行错误命令后立即执行了上述步骤,则此选项有效。否则,请使用更大的数字。

非常感谢Stefan!我必须说你带来了一些很棒的东西。使用这个方法,我找到了最简单的修改/删除历史记录的方式: 1. 使用 ctrl+r 搜索你想要删除/修改的命令。 2. 使用 end 移动命令并删除/修改该命令。 3. 使用 ctrl+n 跳转到下一行,然后 4. 使用 ctrl+c - Saurav Kumar

如果你想立即从同一个终端删除它,首先需要将以下内容添加到你的~/.bashrc文件中。
PROMPT_COMMAND='history -a' 

然后重新启动您的终端。

您可以将其添加到.bashrc文件的任何位置。我已将其添加如下,与其他历史相关内容一起。

enter image description here

通常在一个 bash 会话中,执行的命令直到会话结束才写入 .bash_history 文件,因此 PROMPT_COMMAND='history -a' 命令将立即将命令写入 .bash_history 文件。
现在,如果你在执行命令时犯了错误或者想立即删除它,只需执行以下命令。
sed -i '$d' ~/.bash_history

然后,它就会被删除了。

为了简化操作,你可以给它取一个更简单的别名,并使用它,比如

alias rh ='sed -i '\''$d'\'' ~/.bash_history'

执行rh将从历史记录中删除最后一个执行的命令。
上述是临时别名,只在会话期间有效。要使其永久或持久化,请添加
alias rh = 'sed -i '\''$d'\'' ~/.bash_history' 

to .bashrc

注意

等号两边不应有任何空格

如果您不想使用别名,也可以按照以下步骤操作

创建一个名为rh的命令,并将其放置在/bin目录中:

  • 打开一个文件,命名为rh,并粘贴以下代码,保存并关闭:

    sed -i '$d' ~/.bash_history

  • 使rh可执行,并将其放置在/bin目录中:

    chmod +x rh
    sudo cp rh /bin
  • 现在可以使用rh命令从历史记录中删除最近的命令。


.bashrc文件中添加PROMPT_COMMAND='history -a'的位置在哪里?它具体会做什么?我尝试了sed -i '$d' ~/.bash_history,它可以正常工作而不需要编辑.bashrc!但是别名(alias)的功能却无法使用...如果你能详细解释我的问题并使别名功能正常工作,我将接受你的答案.. :) - Saurav Kumar
@SauravKumar已经编辑了答案。在别名命令中,我错过了单引号和双引号。我的错.. :P - Stormvirux
信不信由你。。别名的事情还是没弄好。。它执行时没有任何错误,但是却没有把记录从“.bash_history”文件中删除。。:P 不过没关系。。我自己写了一条命令并将其放在“/bin”目录下。因为你的命令:sed -i "$d" ~/.bash_history,现在它正常工作了。我接受你的答案。。:) - Saurav Kumar
如果你不介意的话,我想编辑你的回答,以便对其他人有帮助。 - Saurav Kumar
实际上,我已经编辑过了。你需要批准一下。 - Saurav Kumar
我无法批准,因为在我查看之前,它被很多人拒绝了。不管怎样,我通过在Stack Overflow上问问题找到了为什么别名没有起作用的原因。请看我的修改。我会自己添加你的答案。 http://stackoverflow.com/questions/18770979/issue-with-sed-aliasing-and-quotes#18771049 - Stormvirux
请参见其他答案。 - s g

删除多行(例如从1974年到1990年,使用history命令进行检查):
  for i in `seq 1974 1990` ; do history -d 1974 ; done

请注意,要删除的行号始终是相同的,因为您不断地删除该行并转到下一行。

这个便条非常重要。 - Weijun Zhou

如果你在bash中使用了"set -o vi"选项(非常有用的是通过按下Escape键进行向后搜索),那么你可以像在"vi"中一样,通过使用"dd"命令来搜索并删除相应的行。

我发现在输入dd后,我必须再键入jk才能使命令从历史记录中真正清除。如果我输入另一个命令,或者只是按下Enter键,bash似乎会认为它只是一个新命令,并且应该保留旧命令在历史记录中。有趣的是,当它做对了时,它会清除命令,但不会删除它,结果就是空白的历史记录条目。但这已经足够好了,可以删除我在命令行中被迫输入的密码,比其他答案要简单得多,所以非常感谢您发布这个! - Michael Scheper

我遇到一个情况,我的bash历史记录中有一些多余的条目来自一个Yubikey,大约有50个左右,匹配 'ccccc.....'。理想情况下,我希望能够删除与某个模式匹配的条目,我想你可以使用sed或其他工具,假设你的历史记录忽略空白字符。
不过,最后我懒得动手,结果使用vim搜索了 'cccc',然后在每次匹配时使用 'dd' 删除。整个过程不超过一分钟。

1如果你在使用vim的话,你也可以使用:g/cccc/d或者:g/^cccc/d来完成这个操作;或者使用宏qqnddq然后@@(假设你最后一次搜索是为了ccccc)。 - htaccess
@htaccess 这样做肯定更容易,但我也想同时对文件的其余部分进行目视检查。 - Dylan_Larkin