fd 是一个文件搜索工具,主程序 4104192 字节,替掉的是 dir /s /b 再接 findstr。敲 fd 关键字,它按文件名匹配,结果带颜色,路径按层级分段上色。

它解决的问题是「找一个文件要翻三层目录」。Windows 自带的 dir 只能按通配符筛,出了结果还得眼看;fd 支持正则,支持按扩展名和文件类型过滤,还能按层数收窄,结果可以直接交给下一个命令。

这次在 5000 文件、100 个目录的测试树上跑了完整一轮:解压 0.04 秒,版本命令 194 毫秒,搜 4200 个匹配用 166 毫秒,同样条件 dir /s /b 是 351 毫秒。

一个 4104192 字节的搜索器

官方 zip 1535063 字节,解开 14 个条目,主体是 fd.exe 与两套补全脚本。没有安装向导,不写注册表。

文件字节作用
fd.exe4104192主程序,单文件
zip 整体1535063解压后 14 个条目
autocomplete\6 个脚本bash / zsh / fish / PowerShell
LICENSE-MIT1084双授权之一

版本命令 194 毫秒

连跑三次分别是 256 毫秒 / 152 毫秒 / 194 毫秒。第一次的 256 毫秒是杀毒软件扫新文件,后两次才接近真实开销。

# 三次耗时 256 / 152 / 194 毫秒
fd --version
fd 10.5.0

输出只有一行版本号,没有构建信息。要核对包,还是比 zip 的 sha256。

装之前只要一个 PATH

单文件程序,没有运行时依赖。要注意的是命令行的两个习惯差异。

条件本次实测值说明
系统Windows 10 22H2(19045.6466)官方给 msvc 的 x64 与 arm64 包
代码页chcp 65001中文路径在 936 下可能显示成问号
参数顺序先模式后路径写反了路径会被当成搜索词
授权MIT / Apache-2.0可商用,可再分发

zip 只有 1535063 字节,因为匹配引擎和忽略规则,连配色都编译进了 exe。它不依赖 git,但会读 git 仓库里的忽略文件。

5000 文件里 156 毫秒出结果

测试树是 100 个目录、每目录 50 个文件,共 5000 个文件加 200 个子目录。三次跑同一个关键字,结果稳定在 156 到 167 毫秒。

命令结果数耗时
fd mod_ 树目录4200167 / 156 / 166 毫秒
fd -e md README 树目录800193 / 179 / 174 毫秒
fd --glob "*mod_1*.py" 树目录126190 / 171 / 257 毫秒
dir /s /b *mod_*4200363 / 350 / 351 毫秒
测试树规模5000 个文件100 个目录,每目录 50 个文件

差距主要在遍历方式

同样的 4200 个结果,fd 中位 166 毫秒,dir 中位 351 毫秒,差两倍多。dir 要把每个匹配的完整路径拼成字符串再输出,fd 走的是自己的目录遍历,边读边匹配。

第三次 257 毫秒那个是缓存抖动,同一条命令多跑几次就会回到 170 附近。报数时看中位数比看单次更靠谱。

它默认替你忽略什么

这是最容易误判的地方:fd 默认跳过隐藏文件,在 git 仓库里还会读 .gitignore。测试树里放一条 *.md,结果直接从 800 变成 0。

场景结果数说明
普通目录,-e md README800.gitignore 不生效,不是仓库
git 仓库内,同上0.gitignore 写了 *.md,全被忽略
git 仓库内,加 -I800-I 关掉忽略规则

.gitignore 只在仓库里生效

同一个目录,先不 git init 再跑,忽略文件当摆设,800 条照出;git init 之后同样的命令立刻变 0 条。这个差别解释了很多「为什么别人的机器上搜得到」。

要临时关掉忽略规则,加 -I;要连隐藏文件一起搜,加 -H。两个开关管的是不同的事,别混用。

正则与 glob 是两套语法

默认用正则,--glob 之后换成通配符。同一句 *mod_1*.py,不加参数会被当正则解析,星号在正则里表示前一个字符重复,语义完全不同。

# 正则:mod_ 后面任意字符,最后是 .py
fd "mod_.*\.py" 目录

# glob:通配 * 表示任意字符
fd --glob "*mod_1*.py" 目录

# 按扩展名,最常用
fd -e py mod_0 目录
# glob 那条在测试树上出 126 个结果

cmd 里通配符要先加引号

cmd 不会展开 *,但会把带空格的参数拆开。写 --glob "*mod_1*.py" 时引号留给 fd 自己解析,去掉引号在某些 shell 里会被提前展开成文件列表。

实测那 126 个结果是 glob 模式跑出来的,正则模式同样的意图要写成 mod_1.*\.py。

四个真会踩的地方

把路径当成了搜索词

fd D:\项目 不会列出这个目录,它把整串当模式去搜当前目录,结果是 0 条。列目录要写 fd . D:\项目,前面那个点才是模式。

搜不到刚写的文件

隐藏文件默认跳过,git 仓库里的忽略规则也生效。先加 -H 再试,还不行就加 -I。

结果太多刷屏

5000 文件的树上一条泛匹配就是 4200 行。加 --max-results 20 或者 --max-depth 3,再配合 -x 对结果批量操作。

中文文件名显示成问号

conhost 停在 936 代码页时,UTF-8 路径会乱。先 chcp 65001,字体换等宽中文字体。

什么场景值得上

项目目录里找「那个叫 config 的文件」最合适。166 毫秒出 4200 条,按扩展名一收就剩几百条,比在资源管理器里点目录快。

写批处理时也顺手。--max-results 加 -x 能把结果直接喂给下一个命令,不用先落一个临时文件。

反过来,只偶尔找个下载的文件,用资源管理器的搜索框就够。fd 的价值在「重复找」和「嵌进脚本」这两件事上。

项目数值
exe 字节4104192
zip 字节1535063
4200 条结果166 毫秒
dir 同样结果351 毫秒