// Linux · 2025-10-05

fd 工具指南:find 的现代替代品

在命令行世界中,文件搜索是日常操作的核心,但传统的 find 命令语法繁琐、速度较慢,常让人望而却步。fd(fd-find)作为 find 的现代替代品,以其简洁、直观和高性能著称,能快速定位文件和目录,让搜索变得像呼吸一样自然。无论你是开发者、系统管理员还是渗透测试者,fd 都能化繁为简,提升工作效率。

本文将介绍如何用 fd 高效浏览文件树、执行批量操作或集成生态工具,带你从入门到精通。让我们开始探索这个“find 的更好版本”吧!


一、初识 fd

什么是 fd?

fd,全称 fd-find,由开发者 sharkdp 于 2016 年推出,是一个开源命令行工具,基于 Rust 语言编写。它是 find 的简单、快速和用户友好的替代品,专注于文件系统中的条目搜索。 与 find 的复杂语法不同,fd 采用直观的模式:fd PATTERN [PATH],默认递归当前目录,支持正则表达式和 glob 模式,无需手动指定 -name 或 -path。

fd 的设计哲学是“智能默认”:它忽略隐藏文件(以 . 开头)和 .gitignore 模式,启用颜色高亮(类似 ls),并默认大小写不敏感(智能切换:模式含大写时敏感)。这让它特别适合代码仓库、日志目录或项目浏览,而非全功能替换 find(后者更适合复杂过滤)。

支持的核心功能包括:

  • 模式匹配:字面字符串、glob(如 *.rs)或正则(如 ^test_.*\.py$)。
  • 类型过滤:文件(-tf)、目录(-td)、符号链接(-tl)等。
  • 路径控制:指定根目录、排除模式(-E)、最大深度(--max-depth)。
  • 执行集成:并行运行外部命令(-x),如批量解压或编辑。
  • 性能优化:多线程遍历目录,利用 Rust 的零拷贝和并行化,搜索速度比 find 快 5-10 倍,尤其在大仓库中。

在实际场景中,fd 的价值显而易见。例如,在开发中,从 Rust 项目搜 mod.rs 文件;在运维中,快速定位 /etc 下的配置文件;在 forensics 中,扫描备份目录找出特定扩展名的文件。相比 find,fd 的输出更美观(彩色路径),语法更人性化,避免了 find . -name "*pattern*" -type f 的冗长。

最新 v10.2.0(2025 年 9 月)引入了更强的 Unicode 支持和缓存优化,进一步提升了在多语言环境下的表现。 开源社区活跃,GitHub 星标超 30k,常有贡献扩展如新模式解析器。

fd 的核心优势

fd 并非简单包装 find,其优势源于 Rust 的工程精髓和用户导向设计:

  • 超高速度:并行目录遍历(默认线程数 = CPU 核数),利用文件系统缓存,避免不必要的 stat 调用。在 10 万文件仓库中,fd 仅需 0.5 秒,而 find 可能 2-3 秒。 这得益于 SIMD 加速和懒加载。
  • 用户友好:智能大小写、默认忽略 .git 和隐藏文件,减少噪音;颜色编码文件类型(蓝=目录,绿=可执行),提升可读性。
  • 模式灵活:内置正则引擎(Rust regex 库),支持锚点(^、 $)、分组和 Unicode;glob 模式无缝兼容 shell 通配。
  • 可配置性强:配置文件 ~/.config/fd/fd.toml 或环境变量(如 FD_IGNORE=.fdignore),允许自定义忽略列表和主题。v10+ 支持 TOML 格式,便于团队共享。
  • 生态集成:完美与 fzf(模糊选)、ripgrep(内容搜)、bat(高亮)协作,形成“现代 CLI 套件”。

总之,fd 是效率的倍增器:它让文件导航从“痛苦”变“愉悦”,特别在 Git 仓库或大项目中闪光。 相比 locate(需更新数据库)或 ack(内容导向),fd 专注路径搜索,平衡了速度与准确。


二、在 Linux 上安装 fd

安装 fd 简单跨发行版,但需注意包名(如 fd-find)和依赖。核心依赖是 Rust(源码编译时),但预编译包无需。v10.2.0 支持 musl libc,适合 Alpine 等轻量系统。

安装步骤(Debian/Ubuntu/Kali)

  1. 更新系统并安装依赖

    sudo apt update && sudo apt upgrade -y

    无额外运行时依赖,但若源码编译,需 Rust:curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh(>=1.77.2)。

  2. 包管理器安装(推荐)

    • Ubuntu 19.04+ / Debian Buster+ / Kali:
      sudo apt install fd-find -y
      注意:二进制名为 fdfind,创建软链:
      mkdir -p ~/.local/bin
      ln -s $(which fdfind) ~/.local/bin/fd
      确保 ~/.local/bin 在 $PATH(加到 ~/.bashrc:export PATH="$HOME/.local/bin:$PATH")。
    • Fedora 28+:sudo dnf install fd-find -y。
    • Arch:sudo pacman -S fd -y。
    • Alpine:sudo apk add fd(启用 community 仓库)。

    验证:fd --version 输出 fd (fd-find) 10.2.0。

  3. 预编译二进制(离线/自定义)
    从 GitHub Releases 下载:https://github.com/sharkdp/fd/releases/tag/v10.2.0。选 fd-v10.2.0-x86_64-unknown-linux-musl.tar.gz。

    cd ~/Downloads
    tar -xzf fd-v10.2.0-x86_64-unknown-linux-musl.tar.gz
    sudo mv fd-v10.2.0-x86_64-unknown-linux-musl/fd /usr/local/bin/
    sudo chmod +x /usr/local/bin/fd
  4. 源码编译(开发者首选)

    git clone https://github.com/sharkdp/fd.git
    cd fd
    cargo build --release
    sudo cp target/release/fd /usr/local/bin/

其他发行版:RHEL 用 Copr dnf copr enable tkbcopr/fd && dnf install fd;openSUSE zypper in fd。 安装后,运行 fd --help 探索选项。首次使用生成 ~/.config/fd/ 配置目录。


三、fd 基础用法

fd 语法简洁:fd [选项] [模式] [路径]。默认递归当前目录,输出彩色路径列表。这些基础用法覆盖日常 80% 场景,从关键词搜到类型过滤,远胜 find 的冗长。

基本搜索

核心是模式匹配,智能默认让它即开即用。

  • 当前目录搜关键词:

    fd netfl

    示例输出(彩色):

    README.md
    src/netflix.rs
    tests/netflix_test.py

    匹配“netfl”子串,忽略大小写;速度 <0.1s。

  • 指定路径:

    fd passwd /etc

    限 /etc 子树,输出 /etc/passwd 等。

  • 大小写控制:

    fd -i "Error" logs/  # 强制忽略
    fd "Error"          # 智能:含大写时敏感
  • 精确匹配:

    fd '^README$' .  # 正则:以 README 开头结尾
    fd '*.md'        # glob:Markdown 文件

文件类型过滤

用 -t 精炼,内置类型如 file、directory。

  • 仅文件:

    fd -tf "conf" /etc

    输出 /etc/nginx/nginx.conf 等,排除目录。

  • 仅目录:

    fd -td "var" /  # /var, /usr/var 等
  • 扩展名过滤:

    fd -e rs "mod" src/  # Rust 文件含 "mod"
    fd -e {py,js} "test" .  # 多扩展:Python/JS 测试文件
  • 符号链接:

    fd -tl "init" /etc  # 链接如 /etc/init.d

路径与排除

  • 最大深度:

    fd "config" --max-depth 2 project/  # 只搜 2 层
  • 排除模式:

    fd -E node_modules "app" .  # 跳 node_modules

    或用 .fdignore 文件(类似 .gitignore)。

  • 包含隐藏:

    fd -H ".git" .  # 搜隐藏,如 .gitignore

输出控制

  • 仅路径:默认即路径;用 --print0 NUL 分隔脚本:fd . -0 | xargs -0 ls。

  • 列表视图:

    fd --list-details  # 加权限、大小

    示例:

    drwxr-xr-x  4k 2025-10-01  src
    -rw-r--r-- 2k 2025-09-15  README.md

练习:fd . 概览当前目录,感受颜色美观。


四、fd 高级用法

基础后,高级技巧解锁 fd 潜力:执行命令、复杂模式、性能调优。重点实战,融入开发/运维。

执行外部命令

fd 支持并行执行,加速批量操作。

  • 每个匹配运行(-x):

    fd -e zip -x unzip {} -d /tmp/extract  # 并行解压所有 ZIP

    {} 占位全路径;{/.} 无扩展基名。

  • 批次运行(-X):

    fd -g "test_*.py" -X pytest {}  # 一次跑所有测试
    fd -e md -X pandoc {} -o {}.pdf  # 批量转 PDF
  • 占位符高级:

    fd "image" -x convert {} {.}.jpg  # 转 JPEG,{.} 无扩展

高级模式与过滤

  • 全路径匹配:

    fd -p '/home/user/.git/config'  # 匹配完整路径
  • 正则高级:

    fd '^(test|bench)_(.*)\.rs$' src/  # 捕获 test/bench Rust 文件
    fd -a "user.*name" /etc  # -a 全路径正则
  • 线程控制:

    fd --threads 4 "large" /bigdir/  # 限 4 线程,防 overload

性能与调试

  • 忽略自定义:FD_IGNORE=~/.fdignore fd "temp",文件内容如 /tmp/*。
  • VCS 忽略:默认读 .gitignore、/.hgignore 等;用 -I 强制忽略。
  • 调试:fd --log debug 输出遍历日志。

实战:在 Git 仓库 fd -e go "handler" -x go test {/.} 测试所有 handler;在日志 fd -td "2025" /var/log/ --max-depth 1 概览年份目录。


五、fd 与其他工具协作

fd 生态丰富,常与 fzf、rg、bat 组“梦幻组合”,实现模糊搜+内容预览。

fzf 集成(模糊选择)

fzf 是模糊查找器,fd 提供输入源。

  • 默认命令:加到 ~/.bashrc:

    export FZF_DEFAULT_COMMAND='fd --type file --hidden --follow --exclude .git'

    用 fzf 搜文件,Enter 选。

  • 交互预览:

    fd --type file . | fzf --preview 'bat --color=always {}'

    右侧 bat 高亮预览。

  • 目录导航:

    cdf() { cd "$(fd --type directory --hidden --exclude .git | fzf)" }; cdf

    模糊 cd 目录。

ripgrep (rg) 协作(路径+内容)

fd 找路径,rg 搜内容。

  • 内容搜:

    fd -e rs | xargs rg "fn main"

    只搜 Rust 文件的主函数。

  • 交互 rg:

    rg --color=always --line-number --no-heading --smart-case "${1:-}" |
    fzf --ansi --preview "bat --color=always {1} --highlight-line {2}"

    用 fd 限文件源。

其他集成

  • bat 高亮:fd -e md | xargs bat 美化查看。
  • ncdu 磁盘:fd -td | ncdu -f - 分析子目录使用。
  • tldr 示例:tldr fd 快速 man 页。

这些组合让 CLI 像 IDE:fd | fzf | bat 一键浏览项目。


六、最佳实践与案例

最佳实践

  1. 性能调:大目录用 --threads=CPU/2;缓存忽略 FD_DEFAULT_CACHE=~/.cache/fd。
  2. 安全:搜敏感路径加 -E secrets/;脚本用 --print0 避空格。
  3. 集成:alias alias ff='fd -tf';VS Code "files.exclude" 同步 .fdignore。
  4. 团队:共享 .fdignore,统一排除如 node_modules/。

故障排除

  • 无输出:查 $PATH,fd --list-types 验类型。
  • 慢速:--no-ignore-vcs 调试;Rust 版需更新。
  • 模式错:正则用单引号避 shell 转义。

实际案例

案例1:代码开发
Rust 项目:fd -e rs "impl" -x rustfmt {} 批量格式化实现块,节省手动。

案例2:日志运维
fd "error.*2025" /var/log/ --max-depth 2 -x tail -n 50 {} 并行尾随错误日志。

案例3:项目清理
fd -td "build|dist" -x rm -rf {} 清临时目录,安全用 -I 确认。

案例4:Forensics
备份中:fd -e pdf "confidential" -H -x evince {} 交互开敏感 PDF。

案例5:DevOps
Docker 镜像:fd Dockerfile . -X docker build -t {/.} . 批量构建。

这些案例证明 fd 的普适,从 solo 到团队。

原文 https://blog.csdn.net/2301_79518550/article/details/152467413