在 Linux/macOS 终端里找文件,find 几乎是每个开发者的肌肉记忆。但它的语法又臭又长:-name '*.go' -type f、转义引号、还要手动排除 .git。fd 命令(全称 fd-find)是用 Rust 重写的新一代文件查找工具,默认就忽略 .gitignore 和隐藏文件,正则基于 ripgrep 同款引擎,速度飞快,语法直观到几乎不用查文档。本文用 10 个高频场景,带你把 fd 真正用进日常。
一、为什么还要学 fd:find 的三个痛点
find 没问题,只是太”原始”。日常查找时它有三处反直觉:第一,默认连 .git、node_modules 一起扫,结果里一堆噪声;第二,模糊匹配要写 -name '*config*',转义让人头大;第三,想要”找出来再执行命令”得配合 -exec ... \;,语法门槛高。fd 把这三点全默认修好了。
1.1 默认忽略 .gitignore 与隐藏文件
fd 默认读取项目的 .gitignore,自动跳过被忽略的文件,也跳过以点开头的隐藏文件(-H 可强制显示)。这意味着在代码仓库里搜,结果天然干净,不用再手写一堆 -not -path。
1.2 速度来自并行遍历
fd 的搜索核心复用了 ripgrep 的 ignore 与正则引擎,目录遍历是多线程并行的。在几十万文件的仓库里,fd 通常比 find 快一个数量级。代价是它不追求 100% 兼容 find 的全部 POSIX 选项——但日常 90% 的查找场景它都更顺手。
举个直观例子:在仓库根目录找所有名为 main_test.go 的文件。用 find 你得写 find . -type f -name 'main_test.go' -not -path '*/.git/*',光转义引号就够烦;而 fd 只需 fd main_test.go -e go。少打一半字,结果还天然避开了 .git 噪声。这种”所见即所想”的体验,正是 fd 被越来越多开发者设为默认查找工具的原因。
二、安装 fd(多平台)
fd 是单文件二进制,安装极其简单:
# macOS
brew install fd
# Ubuntu / Debian
sudo apt install fd-find
# 注意:Debian/Ubuntu 中命令名为 fdfind,建议建别名 alias fd='fdfind'
# Cargo
cargo install fd-find
# Docker(临时使用,无需安装)
docker run --rm -v "$PWD:/data" -w /data chipsenkbein/fd:latest '*.rs'
验证安装:fd --version 能输出版本号即成功。
三、10 个高频用法(实战)
3.1 按文件名模糊搜索
# 在当前目录递归查找含 config 的文件/目录(不区分大小写用 -i)
fd config
# 显式按完整路径匹配
fd --full-path config
3.2 正则搜索
# 查找以 test 开头、.go 结尾的文件
fd '^test.*\.go$'
# 大小写不敏感
fd -i readme
3.3 限定类型与扩展名
# 只找目录
fd -t d node_modules
# 只找文件,扩展名 py
fd -e py
# 组合:src 目录下所有 .ts 文件
fd -e ts -p '*/src/*'
3.4 限定目录深度
# 只看两层
fd -d 2 config
3.5 对每个结果执行命令
# -X:把结果汇总后执行一条命令
fd -e pdf -X rm
# -x:对每个结果并行执行(适合批处理)
fd -e md -x bat
# 交互式挑选后删除(配合 fzf)
fd -e log | fzf | xargs rm
3.6 排除目录与持久忽略
# 单次排除
fd -E node_modules -E target config
# 持久忽略:语法同 .gitignore
echo 'dist/' >> .fdignore
四、fd 与 fzf / ripgrep 组合拳
fd 真正发力,是在和 fzf、ripgrep 串联时。三者都来自 Rust 现代命令行生态,管道配合天衣无缝:
# fd 找文件,ripgrep 搜内容(先按文件名收窄,再按内容搜索)
fd -e rs -X rg 'tokio'
# fd 作为 fzf 数据源,交互式预览(bat 高亮)
fd --type f | fzf --preview 'bat --color=always {}'
# 找最近 1 小时内改动过的文件
fd -t f --changed-within 1h
这一套组合拳,是很多后端同学终端效率的”三件套”。想看更完整的命令行效率清单,可参考 后端开发者必备的 10 个命令行效率工具。
五、配置文件与别名
# ~/.config/fd/config(持久化常用参数)
--hidden
--no-ignore
--exclude node_modules
Debian/Ubuntu 上命令名是 fdfind,在 ~/.bashrc 或 ~/.zshrc 里加一行别名即可统一:
alias fd='fdfind'
除了别名,也可以用环境变量 FD_OPTIONS 注入默认参数,对所有 fd 调用生效:export FD_OPTIONS="--hidden --exclude node_modules"。这样临时在别的机器上跑 fd,也能保持一致的查找习惯。
还有两个实用细节:fd 的忽略优先级是”命令行参数 > 环境变量 > .fdignore > .gitignore“,排查”为什么没搜到”时按这个顺序查就不会迷路;加上 --list-details 还能顺带输出权限、大小与修改时间,临时当个轻量 ls 用也没问题。
六、在编辑器与 CI 里用 fd
VS Code 内置搜索在超大仓库里会卡,社区扩展(如 search-with-fd)可以把默认搜索后端换成 fd,海量文件时比内置 grep 快很多,配置时参考 2026 年最值得装的 10 个 VS Code 插件 里的效率类扩展思路。CI 脚本里也能用 fd 做”发布前检查有无遗留调试文件”之类的小任务,比 find 写法清爽。
七、性能实测与适用边界:什么时候仍该用 find
fd 不是 find 的替代品,而是”交互式查找”的升级。两类场景里 find 依然不可替代:一是需要精细筛选条件时,比如按修改时间 -mtime、按大小 -size、按权限 -perm 组合筛选,fd 目前支持得有限;二是写需要 POSIX 可移植的部署脚本时,find 几乎 everywhere 都有,而 fd 得先确保目标机装了。日常在本地终端”我想找那个文件”,fd 体验完胜;但 CI 里给一台未必装了 fd 的干净机器写脚本,用 find 更稳。
实用经验法则:让你少打字、快出结果的查找用 fd;需要精确、可移植、条件复杂的用 find。两者共存不冲突,很多团队甚至把 fd 当成 find 的”预览器”——先用 fd 快速定位,确认路径后再交给 find 做精细处理。
八、fd vs find 速查表
| 需求 | find | fd |
|---|---|---|
| 忽略 .gitignore | 需 -not -path | 默认 |
| 隐藏文件 | 默认包含 | 默认排除(加 -H) |
| 模糊名字 | -name ‘*x*’ | fd x |
| 按扩展名 | -name ‘*.py’ | -e py |
| 执行命令 | -exec … \; | -X cmd |
| 并行速度 | 单线程 | 并行遍历 |
九、常见坑与排查清单
fd 上手极快,但几个”默认行为”最容易让人踩坑:它默认跳过隐藏文件和 .gitignore 里的内容,这一点和 find 正好相反,新手第一次搜不到东西往往就是栽在这里;另外它的正则是对整段路径做匹配,和不加引号直接当子串用的直觉也不同。记住下面这五条清单,基本就能避开日常 90% 的困惑。
- Debian/Ubuntu 命令名是
fdfind,记得建别名fd。 - fd 默认排除隐藏文件,想搜
.env这类要点-H。 - fd 默认尊重
.gitignore,要强制包含被忽略文件用-I。 - 管道给
xargs时含空格路径用fd -0 | xargs -0,避免断词。 - 正则里的
.要转义成\.,否则会匹配任意字符。
把 fd 加进你的终端工具箱,配合 fzf、ripgrep,找文件这件事会从”先想半天语法”变成”随手一敲就出结果”。它不取代 find 在脚本里的全部能力,但作为日常交互式查找,fd 几乎全方位更顺手。今天就打开终端 brew install fd(或 apt install fd-find)试试吧。




