“查找”和“定位”的更快替代方法?

ben*_*hsu 28 linux unix locate find

我想使用“查找”和“定位”来搜索我的项目中的源文件,但它们需要很长时间才能运行。我不知道这些程序有没有更快的替代方案,或者提高性能的方法这些程序?

Red*_*ick 19

在项目中搜索源文件

使用更简单的命令

通常,一个项目的源代码很可能在一个地方,也许在几个嵌套不超过两三个深度的子目录中,因此您可以使用(可能)更快的命令,例如

(cd /path/to/project; ls *.c */*.c */*/*.c)
Run Code Online (Sandbox Code Playgroud)

利用项目元数据

在 C 项目中,您通常会有一个 Makefile。在其他项目中,您可能有类似的情况。这些可以是提取文件列表(及其位置)的快速方法,编写一个脚本,利用这些信息来定位文件。我有一个“源”脚本,以便我可以编写像grep variable $(sources programname).

加速查找

搜索较少的地方,而不是尽可能find / …使用find /path/to/project …。尽可能简化选择标准。如果效率更高,请使用管道来推迟某些选择标准。

此外,您可以限制搜索深度。对我来说,这大大提高了“查找”的速度。您可以使用 -maxdepth 开关。例如'-maxdepth 5'

加速定位

确保它正在索引您感兴趣的位置。阅读手册页并使用适合您任务的任何选项。

   -U <dir>
          Create slocate database starting at path <dir>.

   -d <path>
          --database=<path> Specifies the path of databases to search  in.


   -l <level>
          Security  level.   0  turns  security checks off. This will make
          searchs faster.   1  turns  security  checks  on.  This  is  the
          default.
Run Code Online (Sandbox Code Playgroud)

消除搜索的需要

也许您正在搜索是因为您忘记了某些东西在哪里或没有被告知。在前一种情况下,写注释(文档),在后一种情况下,请问?约定、标准和一致性可以提供很大帮助。


ben*_*hsu 13

我使用了 RedGrittyBrick 回答中的“加速定位”部分。我创建了一个较小的数据库:

updatedb -o /home/benhsu/ben.db -U /home/benhsu/ -e "uninteresting/directory1 uninteresting/directory2"
Run Code Online (Sandbox Code Playgroud)

然后指着locate它:locate -d /home/benhsu/ben.db


Tho*_*zat 8

截至 2021 年初,我评估了一些用于类似用例以及与fzf集成的工具:

tl;dr: plocate在大多数情况下是一个非常快速的替代方案mlocatefind对于不需要索引的工具来说,(GNU)通常仍然很难被击败。

locate-喜欢(使用索引)

我比较了常用的mlocateplocate. 在大约 6100 万个文件的数据库中,plocate回答特定查询(几百个结果)的时间约为 0.01 到 0.2 秒,只有对于具有数百万个结果的非常不特定的查询才会变得更慢(> 100 秒)。mlocate在所有测试案例中,查询同一数据库几乎需要 35 到 40 秒的时间。大多数时候plocate比 快多个数量级mlocate

find-likes(目录遍历)

抱歉,很难找到一个好的替代方案,而且结果很大程度上取决于特定的查询。以下是尝试按速度降序查找示例目录中的所有文件(约 200.000 个文件)的一些结果:

  • GNU find ( find -type f):令人惊讶的是,find它通常是最快的工具(~ 0.01 秒)
  • 定位 ( plocate --regexp "^$PWD")(< 0.1 秒)
  • mlocate ( mlocate --regexp "^$PWD"):有趣的是比非正则表达式查询更快(约 5 秒)
  • ripgrep ( rg --files --no-ignore --hidden):快一点,但仍然很慢(~0.5 秒)
  • fd(fdfind --type f在 Debian 上):没有预期的那么快(~0.7 秒)
  • zshglob(**/*和扩展版本):通常非常慢,但在脚本中可以很优雅(〜3秒)

由于目录结构未缓存在 RAM 中,plocate可能会出现问题find,尤其是在寻道时间较长的磁盘 (HDD) 上,但当然需要最新的数据库。

并行化find可能会在受益于命令队列并且可以并行请求数据的系统上提供更好的结果。根据用例,这也可以通过find在不同子树上运行多个实例来在脚本中实现,但性能特征取决于许多因素。

grep-喜欢(查看内容)

有很多类似递归的grep工具具有不同的功能,但大多数提供的功能非常有限,用于根据元数据而不是内容查找文件。即使它们像ag(silversurfer)、rg(ripgrep) 或 一样快ugrep,但如果仅查看文件名,它们不一定很快。


nob*_*bar 7

我使用的一种策略是应用该-maxdepth选项find

find -maxdepth 1 -iname "*target*"
Run Code Online (Sandbox Code Playgroud)

随着深度的增加重复,直到你找到你正在寻找的东西,或者你厌倦了寻找。最初的几次迭代可能会立即返回。

这可确保当您要查找的内容更有可能靠近层次结构的底部时,您不会浪费前期时间查看大量子树的深度。


这是一个自动执行此过程的示例脚本(当您看到所需内容时,请按 Ctrl-C):

(
TARGET="*target*"
for i in $(seq 1 9) ; do
   echo "=== search depth: $i"
   find -mindepth $i -maxdepth $i -iname "$TARGET"
done
echo "=== search depth: 10+"
find -mindepth 10 -iname $TARGET
)
Run Code Online (Sandbox Code Playgroud)

请注意,所涉及的固有冗余(每次传递都必须遍历先前传递中处理的文件夹)将在很大程度上通过磁盘缓存进行优化。

为什么不find将此搜索顺序作为内置功能?也许是因为如果您认为冗余遍历是不可接受的,那么实现起来会很复杂/不可能。该-depth选项的存在暗示了这种可能性,但唉......


Pab*_*o A 5

银色搜寻者

\n\n

您可能会发现它对于快速搜索大量源代码文件的内容很有用。只需输入ag <keyword>。\n这里是我的一些输出apt show silversearcher-ag

\n\n\n\n

我通常将它与:

\n\n
\n

-G --file-search-regex PATTERN\n 仅搜索名称与 PATTERN 匹配的文件。

\n
\n\n
ag -G "css$" important\n
Run Code Online (Sandbox Code Playgroud)\n\n

截屏

\n

  • 据说 [ripgrep](https://github.com/BurntSushi/ripgrep) 算法比 silversearch 更快,而且它还支持 `.gitignore` 文件并跳过 `.git`、`.svn`、`.hg`。 .文件夹。 (4认同)
  • 白银搜索者也尊重“.gitignore”。也就是说,“rg”绝对是令人惊奇的。首先,它支持 unicode。根据我的经验,“rg”的速度始终至少是“ag”的两倍(YMMV),我想这是由于 Rust 的正则表达式解析器,在“ag”刚出现的时候,它显然还没有准备好。 `rg` 可以提供确定性输出(但默认情况下不会),它可以将文件类型列入黑名单,而 `ag` 只能列入白名单,它可以根据大小忽略文件(再见日志)。如果我需要多行匹配,我仍然使用“ag”,而“rg”则无法做到这一点。 (2认同)

小智 5

要查找替换,请查看fd。它具有比原始 find 命令更简单/更直观的界面,并且速度要快得多。

  • 万岁,它是并行的! (2认同)