如何加快大型历史记录的 grep 速度?

如何加快大型历史记录的 grep 速度?

我有无限的.zsh_history,目前是 10k 行。我经常想查看历史记录中具有特定字符串的所有命令,例如curl.如果我history | grep curl这样做,需要很长时间才能完成。如果我grep curl ~/.zsh_history这样做,速度会快得多,但格式会被破坏(时间戳不会解析为日期,分隔符会保留为符号)。

有没有办法解决管道传输缓慢的history问题grep?我看到人们推荐 Ctrl+R 但这显然不是同一件事 - grep 产生一个列表命令,而 Ctrl+R 每次显示一个命令。此外,管道到 grep 允许链接多个 grep 过滤器,而使用 Ctrl+R 则无法实现相同的操作。

答案1

首先,如果您没有做任何比 grep 更复杂的事情,则限制匹配history -m PATTERN可能比 grep 更快。即使您之后应用复杂的过滤器,也可以尝试添加一个简单的过滤器,以-m消除大多数不需要的线条。

如果限制因素是使用 打印完整历史记录所花费的时间history,则有一种黑客方法可以打印 grep (或其他过滤器)选择的历史记录部分。使用fc -p开始一个新的历史记录,并使其读取历史记录的选定部分。未经测试:

function format_history {
  fc -p -a =(cat)
  fc -l 1
}
history 1 | grep curl | format_history

这使用起来不太方便(管道两边都需要一些东西,所以不能只有前缀magic_history_filter)。它在不格式化整个历史记录时获得的速度,可能会因拥有更高级的管道和需要使用临时文件而损失(zsh 只能从可查找文件中读取历史记录,而不是从管道中读取历史记录)。

答案2

这是一个简单的函数,可让您快速搜索整个历史记录中的任何字符串:

histgrep() {
  fc -lm "*${1}*" 1 -1
}

甚至更快:

histgrep() {
  zmodload -i zsh/parameter
  print -raC2 ${(kv)history[(R)*$1*]}
}

其中任何一个都会在每行前面输出一个历史行号,因此您可以使用 执行所需的行!<number>。例如,要将历史行号 2596 插入命令行中,请执行以下操作

!2596

然后按TabEnter

我有大约 3400 行历史记录。对我来说,这样做histgrep cd会产生超过 220 行代码,但第一个版本的函数只需要大约 0.004 秒即可完成,而第二个版本只需大约 0.004 秒即可完成。

答案3

有时你可以跑步history >~/.zsh_history.cache。然后,您可以 grep 该文件以及history该文件中缺少的那些命令的输出。

我不熟悉zsh,因此无法提供将文件内容与命令输出相结合的代码。

答案4

你可以尝试 ripgrep (https://github.com/BurntSushi/ripgrep)实际上更快,并且有许多有用的过滤选项:github 页面有很长的功能列表。

它位于许多发行版的存储库中。

相关内容