当然有一个超级简单的智能方法可以做到这一点,但是由于 zshell 中的历史记录似乎是 fc 的别名,因此无法使用中提到的技巧如何从历史记录中删除一行?。
有关如何执行此操作的任何指示?我的用例是从历史记录中删除最后发出的命令,以便它停止自动完成(主要是当您输入错误的内容并且它不断显示时)。
我知道我可以通过执行以下操作来获取最后发出的命令
history | tail -n 1
,但 History -d 不起作用,我找不到 zsh 的正确文档。
答案1
Zsh 不提供真正的历史编辑功能。命令历史记录基本上是只读的。您所能做的就是批发更换它。
编辑命令历史记录:
- 将其保存到文件中:
fc -W
- 编辑文件
- 从文件加载历史记录:
fc -R
您可以通过设置来选择文件名HISTFILE
。
未经测试的代码:
remove_last_history_entry () {
setopt local_options extended_history no_hist_save_no_dups err_return
local HISTFILE=~/.zsh_history_tmp_$$ SAVEHIST=$HISTSIZE
fc -W
ed -s $HISTFILE <<EOF >/dev/null
d
w
q
EOF
fc -R
}
答案2
通常您可以从 中删除该行~/.zsh_history
,但如果找不到它,请查找~/.zshrc
历史文件的位置。
然后使用您选择的任何文本编辑器删除有问题的行。或者,只需删除整个文件并关闭所有 zsh 实例并启动一个新实例。历史被清除!
答案3
是的,这是一个老话题,但是这些问题都没有回答我的问题,所以我花了很长时间试图弄清楚这一点!
这是我的解决方案,感谢@Gilles有关使用“fc -R”和“fc -W”的提示:)。
将下面的脚本粘贴到您的 .zshrc 文件中。
使用源 .zshrc 重新加载
然后输入“forget”忘记最后一个命令:D。输入“forget 3”即可忘记最后 3 个命令。一些性感的嘶嘶声。
按向上箭头将直接带您到最后一个命令,并且也不会记住“忘记”这个词:)。
更新:添加了主路径,因此它现在可以在所有目录中使用,哈哈。
更新2:添加了传递您想忘记的最后命令数量的功能:D。尝试“忘记 2”来忘记最后 2 个命令:D。
# Put a space at the start of a command to make sure it doesn't get added to the history.
setopt histignorespace
alias forget=' my_remove_last_history_entry' # Added a space in 'my_remove_last_history_entry' so that zsh forgets the 'forget' command :).
# ZSH's history is different from bash,
# so here's my fucntion to remove
# the last item from history.
my_remove_last_history_entry() {
# This sub-function checks if the argument passed is a number.
# Thanks to @yabt on stackoverflow for this :).
is_int() ( return $(test "$@" -eq "$@" > /dev/null 2>&1); )
# Set history file's location
history_file="${HOME}/.zsh_history"
history_temp_file="${history_file}.tmp"
line_cout=$(wc -l $history_file)
# Check if the user passed a number,
# so we can delete x lines from history.
lines_to_remove=1
if [ $# -eq 0 ]; then
# No arguments supplied, so set to one.
lines_to_remove=1
else
# An argument passed. Check if it's a number.
if $(is_int "${1}"); then
lines_to_remove="$1"
else
echo "Unknown argument passed. Exiting..."
return
fi
fi
# Make the number negative, since head -n needs to be negative.
lines_to_remove="-${lines_to_remove}"
fc -W # write current shell's history to the history file.
# Get the files contents minus the last entry(head -n -1 does that)
#cat $history_file | head -n -1 &> $history_temp_file
cat $history_file | head -n "${lines_to_remove}" &> $history_temp_file
mv "$history_temp_file" "$history_file"
fc -R # read history file.
}
所以这里发生了一些事情。该命令将允许我们在任何命令之前键入一个空格,并且它不会添加到历史记录中。
setopt histignorespace
因此,我们可以按空格键,然后输入“echo hi”,按 Enter 键,当我们按向上箭头时,“echo hi”不在我们的历史记录中:)。
请注意别名“forget”在 my_remove_last_history_entry 之前有一个空格。这样 zsh 就不会将我们的“忘记”保存到历史中。
函数解释
ZSH 使用 fc 来记录历史记录或其他内容,因此我们使用“fc -W”将当前命令写入历史文件,然后使用“head -n -1”从文件中删除最后一个命令。我们将该输出保存到临时文件中,然后用临时文件替换原始历史文件。最后使用 fc -R 重新加载历史记录。
然而,该函数存在一个问题,该问题已通过别名修复。
如果我们按函数名称运行该函数,它将删除最后一个命令,即对该函数的调用。这就是为什么我们使用别名并使用空格调用它,这样 zsh 就不会将此函数名称添加到历史文件中,从而使最后一个条目成为我们想要的条目:D。
答案4
我使用 @pandagoespoop 的简化版本 回答,它对我来说工作得很好(限制:在linux上,对于单行命令)。
一项重要的修改是限制新创建的历史文件的权限。重定向到新文件使用默认权限,这将允许组+其他人读取您的历史记录。因此我补充道:
chmod 600 $history_temp_file
完整代码:
setopt hist_ignore_space
alias forget=" forget_last_history_entry"
forget_last_history_entry() {
history_file="${HISTFILE:-${HOME}/.zsh_history}"
history_temp_file="${history_file}.tmp"
fc -W # write current shell's history to the history file.
# Get the files contents minus the last entry(head -n -1 does that)
head -n -1 $history_file > $history_temp_file
chmod 600 $history_temp_file
mv "$history_temp_file" "$history_file"
fc -R # read history file.
}
如果我有这样的声誉,我会发表评论。