#!/usr/bin/python3
import shutil
import time
from itertools import dropwhile
CUTOFF = time.time() - (86400 * 7) # one week ago
hist = []
shutil.copy2(".zsh_history", ".zsh_history.bak")
with open(".zsh_history.bak", "rb") as f:
for l in f.readlines():
if l.startswith(b': '):
# Start of a new history entry
# Add a new tuple (time, history_line) to the list
ts = int(l.split(b':')[1])
hist.append((ts, l))
continue
# Continuation line, append it to the previous entry
prev = hist.pop()
hist.append((prev[0], b''.join([prev[1], l])))
with open(".zsh_history.new", "wb") as f:
# Drop list entries while timestamp < CUTOFF,
# Then write contents of each remaining entry to file
for l in dropwhile(lambda x: x[0] < CUTOFF, hist):
f.write(l[1])
正确,没有基于时间的到期选项
.zsh_history
。可能是因为任何类型的定时到期都需要EXTENDED_HISTORY
格式(包括每个命令的开始时间),并且EXTENDED_HISTORY
是一个新的(er)功能 - 至少比大多数到期选项更新。此外,zsh 功能与“时间”的模糊概念没有最好的关系——只需阅读对基于时间的通配标志的限制即可了解:
除此之外,如果您打开了任何重复删除选项,zsh 将删除旧条目以支持最新条目,因此“旧”条目列表不断变化,使得基于时间的过期变得更加棘手。
如果您确实想这样做,正如 LSerni 所说,自己解析它可能是最好的选择。这样做的一个棘手的事情是,历史中的多行条目是逐字写出的,意思是多行——所以你不能简单地“逐行”解析它,因为有些行不是历史条目,它们'是延续。
我的另一个担心是,除了将它与 zsh 的历史管理直接集成之外,可能没有真正安全的方法可以做到这一点,因为任何修改历史文件的外部代码都存在受到(或干扰)正在运行的
zsh
. 我的意思是,除非您要编写一些bash
仅在您无法登录时运行的东西,例如在启动或关闭过程的单用户部分。此 Python 代码通过将历史记录复制到新文件、从中读取,然后将传递截止日期的条目写入不同的新文件来避免该问题。目标文件可以更改为
.zsh_history
覆盖原始文件,但我对可能发生的任何文件损坏不承担任何责任。早于 的条目
CUTOFF
将被删除(我在示例中使用了 7 天,但您可以轻松更改7
为30
或31
一个月。)假设这是$HOME
作为工作目录运行的。这也假设历史是按时间排序的,我不知道这个假设有多安全。(如果不是真的,您最终可能会保留比预期更多的条目,因为一旦它到达截止时间之后时间戳记的第一个条目,之后的所有内容都会包括在内。因此,在第一个较新条目之后出现的较旧条目将被意外保留。这似乎是一种正确的不正确输出,而不是可能丢弃任何意外的东西。)