关于 fd
指导在 Shell 文件搜索中使用 `fd` 的技能,介绍其选项、默认行为和限制。面向编写脚本或编辑项目文档的开发者,并说明何时回退到 `find`。
主要功能
- 01按名称、扩展名或路径搜索
- 02筛选隐藏及忽略条目
- 03限制深度并排除路径
- 04对搜索结果执行命令
- 05回退到 `find` 的说明
适用场景
- 01在代码仓库中查找文件
- 02替换脚本中的 `find` 命令
- 03搜索被忽略或隐藏的路径
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ petr-korobeinikov/ skills --skill fd安装后在 Claude Code 中输入/fd确认已加载。
详细介绍
fd
搜索文件系统时优先使用 fd,而不是 find。
在大型目录树中,fd 速度更快,
默认行为也更合理
(遵循 .gitignore、智能大小写匹配、默认使用正则表达式),
CLI 也更易用。
权威文档:
https://github.com/sharkdp/fd
(README + fd --help)。
使用任何非简单形式之前,请先对照手册验证。
原因
- 并行遍历目录 —
在大型代码仓库中明显快于
find。 - 开箱即用的合理默认值:
跳过隐藏条目,
在 git
仓库内遵循
.gitignore/.ignore/.fdignore, 智能大小写匹配 (除非模式中包含大写字母,否则不区分大小写), 默认将模式视为正则表达式。 - 默认针对文件名匹配模式,
而不是完整路径 —
fd foo的效果与find . -iname '*foo*'相同, 无需经历通配符和引号的繁琐操作。 - 并行执行
-x、 空字符分隔的输出(-0), 以及一套无需-print/-prune繁琐技巧即可组合使用的选项。
规则
fd PATTERN [PATH]
第一个位置参数是模式;
第二个是搜索根目录
(默认为当前目录)。
第一个参数如果看起来像路径(包含 /),并不会被视为路径 —
请使用 fd . PATH 或 fd --full-path PATTERN。
直接替换
| 不要 | 请用 |
|---|---|
find . -name 'foo*' | fd '^foo' |
find . -iname '*.md' | fd -e md |
find . -type f -name foo | fd -t f foo |
find . -type d -name node_modules | fd -t d node_modules |
find . -type l | fd -t l |
find . -name '*.txt' -delete | fd -e txt -X rm |
find . -name '*.txt' -exec rm {} \; | fd -e txt -x rm |
find . -name node_modules -prune | fd -E node_modules |
find . -size +100M | fd -S +100mi |
find . -mtime -7 | fd --changed-within 7d |
find . -mtime +7 | fd --changed-before 7d |
find . -name '*.go' -print0 | xargs -0 wc -l | fd -e go -0 | xargs -0 wc -l |
find /etc -name passwd | fd passwd /etc |
find / -name foo | fd -u foo / |
若要精确匹配 find -size,
请使用二进制后缀
(ki、mi、gi)—
-S +100m 表示 100 * 10^6 字节,
-S +100mi 表示 100 * 2^20 字节。
对于 find / 搜索,如果还需要遍历隐藏目录和被 .gitignore 忽略的目录,
请添加 -u(即 --no-ignore --hidden)。
常用写法
按扩展名匹配(一个或多个):
fd -e md
fd -e h -e cpp
使用 glob 模式匹配
(-g 让 ** 和 * 按常见方式工作):
fd -g '**/*.test.ts'
fd -g 'libc.so' /usr
匹配完整路径, 而不只是文件名:
fd --full-path 'src/.*\.proto$'
包含隐藏条目
(.git、.vscode 等),
但仍遵循 .gitignore 规则:
fd -H pre-commit
忽略 .gitignore 规则,但仍隐藏隐藏条目:
fd -I node_modules
搜索所有内容 — 包括隐藏和被忽略的内容:
fd -u PATTERN
排除路径 (glob 语法,优先于所有忽略规则,可重复使用):
fd -E .git -E '*.bak' PATTERN
限制深度:
fd -d 2 -t d
组合多个必需模式 (文件名必须全部匹配,默认使用正则表达式):
fd 'foo' --and 'bar' --and 'baz'
对每个结果执行命令
(并行、使用 {} 替换,不需要 \; 终止符):
fd -e jpg -x convert {} {.}.png
将所有结果作为参数一次性执行
(适用于 wc、clang-format、rg 等批处理工具):
fd -e rs -X wc -l
以空字符分隔的形式传递给其他工具:
fd -e go -0 | xargs -0 wc -l
易踩的坑
- 第一个位置参数是模式,而不是路径。
fd /etc/passwd会将/etc/passwd解释为包含/的正则表达式, 并报错, 同时建议使用fd . /etc/passwd或--full-path。 - 默认搜索会排除隐藏项和被
.gitignore忽略的条目。 查找node_modules或.git中的内容时, 添加-H -I(或-u), 否则结果列表会因错误的原因而为空。 --exec默认会并行执行。 输出顺序不确定。 需要串行执行时,传入-j 1(或--threads 1)。- 模式默认是正则表达式。
单独的
.会匹配任意字符; 要匹配字面量.foo,请添加锚点('\.foo$'), 或传入-F/--fixed-strings。 - 大小后缀默认使用十进制 SI 单位。
-S +100m表示100 MB(每个m代表10^6字节); 要精确匹配find -size的语义,请使用mi/ki/gi表示二进制单位。
回退到 find
fd 并非始终可用 —
例如精简型 CI 镜像、
受限服务器、
未包含额外软件包的容器基础镜像。
使用 command -v 探测,并回退到 find:
if command -v fd >/dev/null; then
fd -e log -t f -X rm
else
find . -type f -name '*.log' -exec rm {} +
fi
在受控的本地环境中执行一次性代码片段时,
直接使用 fd。
只有在确定目标主机没有 fd 时,才无条件切换到 find
(例如,镜像中没有 fd 的精简型 Alpine 容器)。
不要仅为满足此技能而自动安装 fd —
缺少时,回退才是正确的做法。
安装 fd
- macOS:
brew install fd - Debian/Ubuntu:
apt install fd-find— 二进制文件名为fdfind, 以避免名称冲突 (alias fd=fdfind是标准的解决方法)。 - Fedora:
dnf install fd-find - Arch:
pacman -S fd - Alpine:
apk add fd - 预编译二进制文件和其他平台: https://github.com/sharkdp/fd/releases
当 mise 管理主机上的工具时,
注册表短名称 fd 会解析为 aqua:sharkdp/fd —
使用 mise use -g fd@<version> 安装
(固定版本,遵循项目的 mise 技能)。
不要使用 ubi: 后端 —
mise 技能已将其禁用。
适用范围
适用于任何通过 shell 代码片段搜索文件系统的地方:
Bash工具调用。SKILL.md/README.md/ 文档中的代码片段。scripts/下的脚本。- Makefile 配方。
- CI 配置。
- 安装说明。
如果编辑文件时遇到 find 调用,
请在同一次编辑中将其替换为等效的 fd 形式
(如果代码片段必须在可能没有 fd 的主机上运行,
则同时添加 find 回退方案)。