目前还无法评论(这已经超出了简单的更正),所以我会将这个作为回答。
这个更正对被接受的答案并不完全适用,例如最后一个命令执行了相当长的时间 - 你的命令中会有杂乱的数字和;
,就像这样:
2017-07-22 19:02:42 | 3
这可以通过将
command_part
中的
sed -re '1s/.{15}//'
换成稍微长一点的
gawk
来解决,这也避免了使用管道。
local command_part="$(gawk "
NR == $line_num_last {
pivot = match(\$0, \";\");
print substr(\$0, pivot+1);
}
NR > $line_num_last {
print;
}" ~/.zsh_history)"
它在处理多行命令中的问题时也存在一些问题,其中一行以
:
开头。这可以通过将
line_num_last
中的
grep -ane '^:' ~/.zsh_history
替换为
grep -anE '^: [0-9]{10}:[0-9]*?;' ~/.zsh_history
(主要是)解决-我说“主要”是因为命令可能包含匹配该表达式的字符串。例如:
% naughty "multiline
> command
> : 0123456789:123;but a command I'm not
> "
这将导致
~/.persistent_history
中的记录被覆盖。
为了解决这个问题,我们需要检查前一个记录是否以
\
结尾(可能存在其他条件,但我还不熟悉这种历史格式),如果是,则
尝试匹配前一个记录。
_get_line_num_last () {
local attempts=0
local line=0
while true; do
local lines="$(grep -anE '^: [0-9]{10}:[0-9]*?;' ~/.zsh_history | \
tail -n $((2 + attempts)) | head -2)"
local previous_line="$(echo "$lines" | head -1)"
local line_attempt=$(echo "$lines" | tail -1 | cut -d':' -f1 | tr -d '\n')
if [[ $line_attempt -ne $HISTORY_LAST_LINE ]] && \
[[ $previous_line == *"\\" ]] && [[ $attempts -eq 0 ]];
then
((attempts+=1))
else
line=$line_attempt
break
fi
done
echo "$line"
}
precmd() {
local line_num_last="$(_get_line_num_last)"
local date_part="$(gawk "NR == $line_num_last {print;}" ~/.zsh_history | cut -c 3-12)"
local fmt_date="$(date -d @${date_part} +'%Y-%m-%d %H:%M:%S')"
local command_part="$(gawk "
NR == $line_num_last {
pivot = match(\$0, \";\");
print substr(\$0, pivot+1);
}
NR > $line_num_last {
print;
}" ~/.zsh_history)"
if [ "$command_part" != "$PERSISTENT_HISTORY_LAST" ]
then
echo "${fmt_date} | ${command_part}" >> ~/.persistent_history
export PERSISTENT_HISTORY_LAST="$command_part"
export HISTORY_LAST_LINE=$((1 + $(wc -l < ~/.zsh_history)))
fi
}
PROMPT_COMMAND
。使用grep -o
或cut
或类似工具替换[[
的用法是可行的,但取决于zsh中history
的确切输出。 - Etan ReisnerPROMPT_COMMAND
,这个链接应该会有帮助。关于[[
的部分,我刚刚发现使用history
命令,Bash 会在最后一行给出最新的命令(在这种情况下是history
)。但在 Zsh 下,history
命令不会返回最新的命令,而是返回在history
命令之前使用的命令。有什么想法吗? :-) - astroboylrxHISTFILE
并将HISTSIZE
和SAVEHIST
设置为一些荒谬的大尺寸(我的是100,000,我认为没有理由使它们更大,因为我在iTerm2中记录了所有终端会话 - 所有命令+输出,我的提示符中的时间精确到秒)。默认历史记录格式具有关联的POSIX时间戳,这比您的更准确,因为您的没有tzinfo。 - 4ae1e1