以下解决方案相当简单.他们没有涵盖很多角落案例:
解决方案的好处在于它们非常容易实现.
解决方案1:一个大文件
事实:寻求死得很慢,阅读一个大文件往往更快.
鉴于这些事实,我们的想法是简单地创建一个包含所有文件及其所有内容的索引 - 每行包含文件名和行号:
索引目录:
find . -type f -print0 | xargs -0 grep -Han . > .index
Run Code Online (Sandbox Code Playgroud)
使用索引:
grep foo .index
Run Code Online (Sandbox Code Playgroud)
解决方案2:一个大的压缩文件
事实:硬盘很慢.寻求死得很慢.多核CPU是正常的.
因此,读取压缩文件并在运行时解压缩可能比读取未压缩文件更快 - 特别是如果RAM足以缓存压缩文件但对未压缩文件不够.
索引目录:
find . -type f -print0 | xargs -0 grep -Han . | pbzip2 > .index
Run Code Online (Sandbox Code Playgroud)
使用索引:
pbzcat .index | grep foo
Run Code Online (Sandbox Code Playgroud)
解决方案3:使用索引查找潜在候选人
生成索引可能非常耗时,您可能不希望为dir中的每个更改执行此操作.
为了加快速度,只需使用索引来识别可能匹配的文件名,并通过那些(希望数量有限的)文件执行实际的grep.这将发现不再匹配的文件,但不会发现匹配的新文件.
的sort -u
需要,避免多次grepping相同的文件.
索引目录:
find . -type f -print0 | xargs -0 grep -Han . | pbzip2 > .index
Run Code Online (Sandbox Code Playgroud)
使用索引:
pbzcat .index | grep foo | sed s/:.*// | sort -u | xargs grep foo
Run Code Online (Sandbox Code Playgroud)
解决方案4:附加到索引
重新创建完整索引可能非常慢.如果大多数dir保持不变,您只需使用新更改的文件追加到索引即可.索引将再次仅用于查找潜在候选项,因此如果文件不再匹配,则在浏览实际文件时将发现该索引.
索引目录:
find . -type f -print0 | xargs -0 grep -Han . | pbzip2 > .index
Run Code Online (Sandbox Code Playgroud)
附加到索引:
find . -type f -newer .index -print0 | xargs -0 grep -Han . | pbzip2 >> .index
Run Code Online (Sandbox Code Playgroud)
使用索引:
pbzcat .index | grep foo | sed s/:.*// | sort -u | xargs grep foo
Run Code Online (Sandbox Code Playgroud)
解决方案5:使用git
pzstd
可以通过git存储库grep.但它似乎做了很多寻求,并且在我的系统上比解决方案4慢4倍.
好的部分是.git索引小于.index.bz2.
索引目录:
git init
git add .
Run Code Online (Sandbox Code Playgroud)
附加到索引:
git add .
Run Code Online (Sandbox Code Playgroud)
使用索引:
git grep foo
Run Code Online (Sandbox Code Playgroud)
解决方案6:优化git
Git将其数据放入许多小文件中.这导致了寻求.但是你可以让git将小文件压缩成几个更大的文件:
git gc --aggressive
Run Code Online (Sandbox Code Playgroud)
这需要一段时间,但它在几个文件中非常有效地打包索引.
现在你可以这样做:
find .git -type f | xargs cat >/dev/null
git grep foo
Run Code Online (Sandbox Code Playgroud)
pbzip2
会做很多寻求索引,但通过pbzcat
先运行,你把整个索引放入RAM.
添加到索引与解决方案5中的相同,但是在系统空闲时git grep
立即运行以避免许多小文件,并git
节省更多磁盘空间.
cat
如果删除文件,则不会释放磁盘空间.因此,如果删除大量数据,请删除git gc
并git gc --aggressive
重新执行.
这篇 grep-cache文章有一个用于缓存 grep 结果的脚本。他的例子是在安装了linux工具的windows上运行的,因此只需很少的修改就可以轻松地在nix/mac上使用。无论如何,它主要只是一个 perl 脚本。
此外,文件系统本身(假设您使用 *nix)经常缓存最近读取的数据,导致未来的 grep 时间更快,因为 grep 有效地搜索虚拟内存而不是磁盘。
缓存通常位于/proc/sys/vm/drop_caches
如果您想手动擦除它以查看从未缓存到缓存 grep 的速度增加。