在日常命令行工作中,反复敲 cd、grep、ps 找文件、找进程、翻历史命令,是最耗时的重复劳动之一。fzf 是一款轻量的命令行模糊查找工具(fuzzy finder),它把任意列表变成可交互的实时筛选界面:输入几个字符就能在文件树、命令历史、Git 分支、运行进程中秒级定位目标。本文从安装到与 bat、fd、ripgrep 的组合实战,带你把 fzf 真正用进日常流程。
一、fzf 是什么:交互式模糊查找器
fzf 本质是一个通用的模糊查找前端,不关心数据来源。它从标准输入读取一行行候选,打开一个全屏(或可嵌入)的交互面板,你边打字边高亮匹配,回车即输出选中行。它用 Go 编写,单二进制、零依赖,macOS、Linux、Windows 都能跑。
和传统 grep 的“精确包含”不同,fzf 做的是模糊匹配:输入 srccrtl 也能命中 src/controller/UserController.php。这正是它快的原因——你只需记住关键词的片段,不必拼全路径或全文件名。
fzf 的匹配得分并非简单“包含即命中”。它内置一套评分算法,更偏爱连续匹配、首字母与单词边界匹配,以及更短的路径;例如输入 usrlog 时,usr/local/log 会比 userlogins 排在更前。需要更激进的排序可用 --tiebreak 指定次级排序键,需要完全精确匹配时加 --exact 即可退回“子串包含”模式。理解这套打分逻辑,能帮你写出命中率更高的查询词。
二、安装与基础用法
各平台安装
# macOS
brew install fzf
# Ubuntu / Debian
sudo apt install fzf
# Arch
sudo pacman -S fzf
# 安装后把键绑定与补全注入 shell(以 Homebrew 为例)
$(brew --prefix)/opt/fzf/install
安装后建议执行官方 install 脚本,它会把 Ctrl-T / Ctrl-R / Alt-C 三组快捷键和补全注入当前 shell,否则只能手动调用 fzf 命令。
fzf 提供几个环境变量来自定义数据源与默认行为:FZF_DEFAULT_COMMAND 决定 Ctrl-T 查找文件时用的命令(默认常是系统的 find),把它改成 fd 能立刻获得更快、更智能的查找;FZF_CTRL_R_OPTS 可给历史搜索加预览;FZF_DEFAULT_OPTS 则是对所有 fzf 调用统一生效的全局参数。把它写成 --preview 'bat --color=always {}',以后每次查找文件都能顺手看到内容。
管道里的基础用法
最简单的用法是把任何命令的输出通过管道交给 fzf,回车打印被选中的整行,可再接管道继续处理。
# 在进程列表里实时筛选,回车打印被选中的整行
ps aux | fzf
# 在历史命令里查找,选中后回车直接执行
history | fzf
# 杀掉选中的进程
kill -9 $(ps aux | fzf | awk '{print $2}')
三、三个默认键绑定(效率核心)
fzf 安装脚本会注册三组 shell 快捷键,这是它“无感提速”的关键。习惯后你会发现:找文件不再 ls 翻页,翻历史不再反复按上下键,进目录不再 cd 拼长路径。
| 快捷键 | 触发位置 | 作用 |
|---|---|---|
| Ctrl-T | 任意命令行 | 插入文件(在当前目录递归查找) |
| Ctrl-R | 任意命令行 | 搜索命令历史并替换当前行 |
| Alt-C | 任意命令行 | 跳转到子目录(cd) |
在交互面板里,除了输入匹配,还可以用上下方向键移动光标、Tab 多选(配合 -m)、Ctrl-J/K 或 Ctrl-N/P 移动、Ctrl-Y 把选中项复制到剪贴板。这些导航键让 fzf 既能“一眼扫完”也能“精挑细选”,对长列表尤其友好;配合多选,一次筛选就能产出一组目标供后续批量处理。
四、与现代 CLI 组合:fd + ripgrep + bat
单独用 fzf 只能搜文件名;配合本站介绍过的现代命令行工具,能力直接翻倍。fd 替代 find 按文件名模糊查找,ripgrep 替代 grep 按内容搜索,bat 替代 cat 带语法高亮预览。
组合示例:用 fd 列文件、fzf 筛选、bat 预览内容。在右侧预览窗口里直接看到文件内容,确认无误再回车——这比先 ls 再 cat 流畅得多。
# 找文件并实时预览内容
fd --type f | fzf --preview 'bat --color=always --style=plain {}'
# 按内容搜到文件后再预览
rg --files-with-matches "TODO" | fzf --preview 'bat --color=always {}'
| 场景 | 命令骨架 |
|---|---|
| 找文件并预览 | fd | fzf –preview ‘bat {}’ |
| 按内容搜文件 | rg -l 关键词 | fzf –preview ‘bat {}’ |
| 跳目录 | fd -t d | fzf –bind ‘enter:execute(cd {})’ |
| 杀进程 | ps aux | fzf | awk ‘{print $2}’ | xargs kill |
五、预览窗口与自定义命令
--preview 是 fzf 最强的能力。它支持对当前高亮项执行任意命令并把输出渲染到右侧窗口,{} 会被替换成选中行。配合 --preview-window=right:60% 可控制预览区位置与宽度。
# 目录预览树、文件预览内容
ls -la | fzf --preview 'if [ -d {} ]; then tree -L 2 {}; else bat --color=always {}; fi'
预览窗口的位置与形态都能调:--preview-window=up:30% 把它放上方、hidden 默认隐藏按需空格展开、wrap 自动换行、border 加边框。配合环境变量一次设好,就能让每次 fzf 都有一致的预览体验,而不必每条命令都重复写一长串参数。
六、在 Shell 与编辑器里集成
zsh 深度集成
fzf 自带 key-bindings.zsh。进阶玩家可在 .zshrc 里重写 Ctrl-R,用 fzf 搜索历史并保留完整命令行。
fzf-history-widget() {
local sel
sel=$(fc -rl 1 | awk '{$1="";print substr($0,2)}' | fzf --query "$LBUFFER")
BUFFER=$sel
zle redisplay
}
zle -N fzf-history-widget
bindkey '^R' fzf-history-widget
与 Vim / Neovim 联动
插件 fzf.vim 让你在编辑器内模糊查找文件、缓冲区、Git 文件与 Tags,复用同一套 fzf 交互,比原生 :e 拼路径快得多。
" 查找文件并打开
:Files
" 按内容搜(依赖 ripgrep)
:Rg 关键词
" 跳转到函数定义(依赖 ctags)
:Tags
七、进阶:用 fzf 改造 Git 工作流
Git 分支、提交、文件多到记不住名字,fzf 是绝佳的“选择器”。-m 开启多选,配合 git add 精准暂存,避免 git add . 误带文件。
# 交互式切分支
git branch | fzf | xargs git checkout
# 交互式挑提交看 diff
git log --oneline | fzf --preview 'git show {1}' | awk '{print $1}' | xargs git show
# 多选暂存指定文件
git status -s | fzf -m | awk '{print $2}' | xargs git add
除了 Git,fzf 在容器与集群运维里同样好用:筛选 Docker 容器再 exec、挑选 kubectl 上下文或 Pod 再 logs,都是“列表选一”的典型场景,比手敲一长串容器 ID 或 Pod 名稳妥得多。
# 选容器并进入
docker ps | fzf | awk '{print $1}' | xargs -I{} docker exec -it {} sh
# 选 Pod 看日志
kubectl get pods | fzf | awk '{print $1}' | xargs -I{} kubectl logs -f {}
八、性能与避坑
| 现象 | 原因与对策 |
|---|---|
| 列表卡顿 | 候选过多时先用 fd/rg 预筛,别直接 fzf 大目录 |
| 中文输入法冲突 | 终端下用英文输入匹配,中文做内容搜索 |
| 预览闪烁 | 加 –preview-window=nohidden 或减少预览命令开销 |
| 快捷键不生效 | 确认 install 脚本已执行,或手动 source key-bindings |
另外,fzf 默认是大小写不敏感的模糊匹配,需要精确可用 --exact;需要路径模式可用 --query 预填关键词。
九、30 秒上手清单
1. 装好 fzf 并执行 install 脚本,让 Ctrl-T / Ctrl-R / Alt-C 生效。
2. 记住“任何命令 | fzf”这一万能句式。
3. 装上 fd、ripgrep、bat,用 --preview 'bat {}' 看内容。
4. 在 .zshrc 加一行 export FZF_DEFAULT_OPTS='--preview "bat --color=always {}"',全局生效预览。
5. Git 重度用户把分支 / 提交选择接上 fzf。
十、fzf 与同类工具对比
命令行模糊查找器不止 fzf 一个。peco、skim(Rust 实现,兼容 fzf 接口)、fzy 都是同类;fzf 胜在生态成熟、键绑定完善、预览能力强,且自带 fzf-tmux 可在分屏里弹出。若你已在用 zoxide 这类现代工具,把“跳转”和“查找”拆开反而更顺手——zoxide 负责“去哪”,fzf 负责“选哪个”,两者互补而不重叠。
| 工具 | 语言 | 特点 |
|---|---|---|
| fzf | Go | 生态最全、预览强、键绑定完善 |
| skim | Rust | 兼容 fzf 接口、更轻量 |
| peco | Go | 简洁、跨平台 |
| fzy | C | 极致轻量、只做匹配 |
总结:fzf 不解决某个特定问题,而是给“从列表里选一个”这件事统一提速。它体积小、零依赖、和管道哲学天然契合,一旦用顺手就很难回去。配合 fd、ripgrep、bat 这套现代命令行组合,你的终端效率会有质的提升。更多终端与开发工具技巧,可参考本站的 bat 实战、fd 实战、ripgrep 实战 与 zoxide 实战 等文章。




