fzf 命令行模糊查找器上手指南
fzf 是 junegunn 用 Go 写的命令行模糊查找器,从标准输入读候选、把选中项写到标准输出,能接进任何 shell 管道。这篇文章讲清它的安装方式、最小可用示例、主要参数与输出落在哪里,并列出真实用户踩过的坑和同类项目对比,帮读者判断它值不值得接进自己的终端工作流。
在终端里找一个文件、翻一段命令历史、从几百个分支里挑一个切换,用 cd 加 Tab 补全往往要敲很长一串路径。fzf 把这类「从一堆候选里挑一个」的动作压缩成一次模糊匹配:候选行从标准输入进来,它在终端里弹出一个可交互列表,敲几个字符实时筛选,回车把选中项送到标准输出。
fzf 是一个用 Go 写的命令行模糊查找器,从标准输入读候选列表,让人按键筛出其中一项并从标准输出返回,凡是需要在终端里选文件、选历史命令、选进程的场景都用得上它。
它本身不生产数据,只在管道中间做一次交互式挑选。git ls-files | fzf、ps -ef | fzf、把文件列表重定向进去,都是同一个模型:左边随便什么命令产出候选,右边接上拿到选中项之后的动作。仓库地址是 https://github.com/junegunn/fzf,用 MIT 许可证发布,主要语言 Go(代码占比 64.7%,其余是 Ruby 21.8%、Shell 7.0%、Vim Script 2.8%、Nushell 2.2%、Assembly 0.9%),目前 83278 个 Star、3904 个 Fork、450 个 Watcher,开放 Issue 332 个。

五分钟先跑通
走包管理器最快。macOS 和 Linux 上用 Homebrew 是 brew install fzf;用 mise 是 mise use -g fzf@latest。各发行版也有官方包,README 列出的包括 sudo apt install fzf(Debian 9+/Ubuntu 19.10+)、sudo dnf install fzf(Fedora)、sudo pacman -S fzf(Arch)、sudo apk add fzf(Alpine)、sudo zypper install fzf(openSUSE)。Windows 上可以用 choco install fzf、scoop install fzf 或 winget install fzf。
也可以从源码装:把仓库克隆到任意目录,运行仓库根目录下的 install 脚本。README 给出的克隆命令是 git clone --depth 1。仓库里还带了一个 uninstall 脚本用于卸载。
装完二进制不等于功能齐了。README 用 IMPORTANT 标注了一件事:键位绑定和模糊补全属于 shell integration,要按文档单独设置,相关脚本在 shell/ 目录,install 脚本也会处理这一步。
最短能跑通的例子,都是对标准输入做筛选:
ls | fzf
git ls-files | fzf
git ls-files | fzf --preview "head -$LINES {}" --color light --margin 5,20
第一条把当前目录的条目列出来让你挑,第二条在版本控制的文件里挑,第三条边挑边在预览窗口看文件开头几行。这三条都不需要额外配置。
跑通之后你会得到什么
fzf 没有输出文件,也没有报告目录。它的全部产出就是被选中那一行的内容,写到标准输出,直接能被别的命令接住:
vim "$(fzf)"
git checkout "$(git branch | fzf)"
终端里敲完回车,选中项就进了下一条命令的参数位置。原本需要复制粘贴的中间步骤,变成了一条管道。
拿到这个之后,能接着做三件事。把键位绑定接上,之后按 Ctrl-R 就能在命令历史里做模糊搜索,路径、进程 ID、主机名、环境变量和别名也能用模糊补全。在 Vim/Neovim 里用配套插件,仓库有 plugin/ 目录和 README-VIM.md。用预览窗口和重新加载候选列表这两组能力,把普通 shell 脚本改造成带界面的小工具,ADVANCED.md 专门讲这部分。
主要功能
- 交互式筛选与选择:读标准输入,输出选中的那一行。不选就退出,退出码约定仓库里没有说明。
- 模糊匹配与搜索语法:README 有独立的 Search syntax 章节,支持在查询里组合条件做筛选。
- 两种显示模式:
--height让列表只占指定高度,不铺满终端;--popup走 tmux 弹出窗口,tmux 3.7 或以上会改成浮动窗(floating pane),这是 v0.74.0 的改动。 - 预览窗口:
--preview给当前选中项跑一条命令,--preview-window控制窗口位置与尺寸,预览内容支持图片。 - Shell 集成:覆盖 bash、zsh、fish、Nushell,包含键位绑定与模糊补全。Ctrl-R 用于搜索历史,文件与目录、进程 ID、主机名、环境变量与别名都有对应的补全源,也能自己定义补全来源。
- 编辑器插件:Vim 与 Neovim 插件,文档在 README-VIM.md,代码在 plugin/ 目录。
- 可编程的事件驱动接口:可以执行外部程序、重新加载候选列表。README 举了三个用法:按 CTRL-R 刷新进程列表、按 CTRL-D 或 CTRL-F 在多个数据源之间切换、与 ripgrep 做交互式集成。
- 外观定制:
--color、--margin一类选项,仓库里还提供了一个 fzf Theme Playground 的入口。
分发形态是单个二进制文件,README 把它列为第一条特性。性能方面,v0.74.3 让非 ASCII 输入的处理明显变快:ASCII 查询最高快 16 倍,非 ASCII 查询最高快 12 倍,带重音的拉丁字母输入读取快 37%,CJK 输入内存占用减少 29%,ASCII 输入不受影响。v0.74.2 针对短查询,单字符查询最高快 2.4 倍,双字符查询最高快 1.4 倍。
常用参数与配置
--height:列表按指定高度显示,不占据整个终端。--popup:走 tmux 弹出模式。tmux 3.7 或以上启动为浮动窗,低版本还是传统弹出窗口。--preview:给选中项执行预览命令,{}是当前行的占位符。--preview-window:控制预览窗口的位置与大小。--margin:给界面留边距,README 与 Issue 里的例子用过--margin 5,20。--color:配色方案,例子中用过--color light。
README 里还有 Environment variables 一节,但仓库在本次引用的范围内没有列出具体变量名。构建相关配置写在 BUILD.md,编译入口是 Makefile。
结果在哪里看
结果就在标准输出。没有任何文件生成,也没有需要事后查看的报告目录。你在列表里回车,选中的那一行出现在 stdout;用 ESC 或其他方式取消时仓库里没有说明会输出什么。
用了 Vim/Neovim 插件的话,结果体现在编辑器打开的文件或缓冲区上。用了 --preview 的话,预览内容显示在列表旁边的窗口,那是给人看的,不是结果。
想验证行为是否正常,仓库里有 test/ 目录和 Makefile,构建步骤在 BUILD.md。
实际使用中的坑
332 个开放 Issue 里,下面几条评论数最多,也最能反映真实使用中的摩擦,状态都是已解决。
- Ubuntu 上
--preview报 Failed to read /dev/tty:这是讨论最热的一条(70 条评论、58 个 reaction),预览命令拿不到终端设备直接报错。已解决。 - Neovim 里
:FZF选中文件后不响应:有用户描述按回车后编辑器卡住,再按几次回车才恢复(48 条评论)。已解决。 - 更早的 Neovim 兼容性问题:48 条评论记录的情况是,fzf 的 Vim 插件在非 tmux 环境下依赖
:!运行 fzf,而 Neovim 当时不支持这种用法。已解决。 - 搜索默认不含隐藏文件:有用户找不到对应的开关(43 条评论、22 个 reaction)。已解决。
- 内容显示迟滞:有反馈称 fzf 一度要等约 0.5 秒才显示内容(31 条评论)。已解决。
版本层面的修复也有记录,v0.74.4 修掉了一个转义序列被拆成两次读取时当成片段解析、把剩余内容漏进查询的问题。
同类项目对比
| 项目 | 适合谁 | 部署方式 | 主要限制 | 什么情况下选它更合适 | 项目地址 |
|---|---|---|---|---|---|
| fzf | 已经在用 shell 管道、想自己决定交互细节的开发者与运维,尤其是每天在终端里翻文件、历史与 git 提交的人 | 单个二进制;brew、apt、dnf、pacman、choco、scoop、winget 等包管理器都能装,也能克隆仓库跑 install 脚本 | 本体只提供筛选交互,键位绑定与模糊补全要做额外的 shell integration;--popup 依赖 tmux,且需要 3.7 以上才是浮动窗;仓库没有中文文档 | 你需要一个能塞进任意现有管道的通用组件,而不是一整套预设好的环境 | fzf |
| Matt-FTW/dotfiles | 用 Hyprland 做桌面、想直接拿一份成套装潢配置的人 | 仓库没有说明 | 未逐一核实 | 你想连桌面环境一起换掉,而不是只解决终端里选文件这一步 | Matt-FTW/dotfiles |
| Olical/dotfiles | 在 Linux 上跑 sway,用 ghostty、fish、neovim 的开发者,想拿一份别人在用的配置当起点 | 仓库没有说明 | 未逐一核实;它是配置集,本身不含 fzf 本体 | 你要的是一份已经组装好的 shell 与编辑器环境,不想从零逐个组件配 | Olical/dotfiles |
这两个 dotfiles 仓库与本项目的差别在交付物形态:它们给出一份别人调好的 shell、编辑器、窗口管理器配置,fzf 这类组件只是其中可能被引用的一环。fzf 给的是一个可编程的筛选器,键位、补全、预览都要自己按文档接上。如果你要的是开箱就能用的终端环境,先去看 dotfiles 更省事;等你知道自己想怎么改,再回来把 fzf 拆出来单独用。
什么情况下别用它
- 你不想动 shell 配置。装完得到的只是裸二进制,Ctrl-R 历史搜索、路径补全这些都要按文档做 shell integration 才会生效。
- 你要解决的是「按文件内容全局搜索」。fzf 不建索引、不主动扫盘,它只对喂进来的候选行做匹配,候选列表得靠 ripgrep 之类的工具先产出。
- 你在 Windows 原生环境下工作,也不使用 tmux。弹出模式依赖 tmux,Issue 里关于 Windows 的讨论基本围绕 gvim 和 WSL 展开。
- 你的候选集以非 ASCII 或 CJK 内容为主,且版本停在 v0.74.3 之前。这一轮的读取与内存改进都集中在该版本及之后。
- 你需要的是一套开箱可用的终端与编辑器环境。fzf 是其中一个零件,不是那套环境本身。
焚评:这个项目的量化评分
本项目的选题来自 焚.com(一个按公开公式给 GitHub 项目打分的站)。焚评当前总分 10.0 分(满分 10)。下表是各维度的得分:
| 评分维度 | 得分 |
|---|---|
| 热度动量(权重 25%) | 10.0 / 10 |
| 开发活跃(权重 25%) | 10.0 / 10 |
| 社区响应(权重 15%) | 10.0 / 10 |
| 文档质量(权重 15%) | 10.0 / 10 |
| 发布节奏(权重 10%) | 9.7 / 10 |
| 风险控制(权重 10%) | 10.0 / 10 |
评分口径、权重与计算方式见焚.com 的评分方法页;数据随 GitHub 指标刷新,具体数值以焚.com 当前页面为准。本文正文为诀.com 独立撰写,评分数据由焚.com 授权引用。
内容核验说明
fzf 的中文资料多是零散片段,这篇把安装、最小示例、参数、输出落到哪里和踩过的坑串成一条线,并强调装完只是裸二进制,键位绑定与模糊补全要另做 shell integration。文末与 dotfiles 的对比也给了取舍依据。适合每天在终端翻文件、历史和分支的人。文中 Star、Issue、性能倍数与焚评评分均来自引用方公开数据,诀.com 未独立验证。
Star、Fork、Watcher、Issue 数量与语言占比取自 GitHub 页面;性能提升倍数及 v0.74.2、v0.74.3、v0.74.4 的修复记录来自项目 README 与发布说明,诀.com 未独立复现;焚评评分为焚.com 按其公开公式给出,非本站测量;五条高频 Issue 的评论数与已解决状态取自仓库 Issue 列表,修复细节未逐条核对。用法效果随 shell、终端版本不同而不保证一致。用户反馈摘要
根据仓库 Issue 来看,抓到 11 条反馈,状态均标记为已解决。讨论集中在几类摩擦:预览失败,如 Ubuntu 下 Failed to read /dev/tty、SSH 下无法打开 /dev/tty,以及在 kitty icat、sixel 终端里预览图片的诉求;shell 集成失效,包括 Ctrl-R/Ctrl-T 无响应并提示 height required、cd Tab 补全不工作、FZF_DEFAULT_COMMAND 报错;另有搜索是否含隐藏文件、查询中转义空格、把显示字段与返回字段分离等功能请求。
基于该仓库公开 Issue 整理,只反映提交者报告的现象与诉求,不代表诀.com 立场,也不代表问题已被确认。项目来源与说明
开源项目:junegunn(junegunn)
本文由诀.com 编辑基于该项目的公开信息独立撰写,属原创解读,不是对项目文档的翻译或转载;文中提到的功能与参数以官方仓库为准,代码与文档版权归原作者所有。
查看项目仓库