fzf 在终端里模糊搜索任意东西(文件、历史、分支、进程)

fzf 是命令行模糊搜索工具,几乎所有 "我要从一堆东西里挑一个" 的场景
都能用。一旦养成习惯,效率提升明显。

安装

# Debian/Ubuntu (22.04+)
sudo apt install -y fzf

# 或最新版(推荐)
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

install 脚本会问你要不要装 shell key binding + completion,都选 y。

基本 shell 集成

装完后,bash / zsh 里有这几个快捷键:

  • Ctrl-T:把"文件路径"插到光标处(fuzzy 选择当前目录下的文件)
  • Ctrl-R:搜索 shell 命令历史
  • Alt-C:fuzzy cd 到子目录
  • **Tab`:通用 completion(命令、文件名、kill PID 等)

最常用的是 Ctrl-R —— 一旦用上就忘不掉。

常用模式

选文件打开

vim "$(fzf)"

选分支 checkout

git checkout "$(git branch --all | fzf | sed 's/^..//; s/remotes\/origin\///')"

kill 进程

ps -ef | fzf -m | awk '{print $2}' | xargs kill
# -m 多选

选 docker 容器进入

docker exec -it "$(docker ps | fzf | awk '{print $1}')" bash

写成函数 / alias

# 模糊 cd
fcd() {
  cd "$(fd -t d --hidden --exclude .git . "${1:-.}" | fzf)"
}

# fzf-grep:模糊搜文件内容
fg() {
  local file
  file=$(rg --line-number --no-heading --color=always "${1:-.}" \
    | fzf --ansi --delimiter=':' \
          --preview 'bat --color=always {1} --highlight-line {2}' \
    | cut -d':' -f1)
  [[ -n "$file" ]] && ${EDITOR:-vim} "$file"
}

# fzf-git-log:浏览 git log
fgl() {
  git log --oneline --color=always | fzf --ansi \
    --preview 'git show --color=always {1}' \
    --bind 'enter:execute(git show {1} | less -R)'
}

与其他工具组合

配合 ripgrep + bat

export FZF_DEFAULT_COMMAND='rg --files --hidden --glob "!.git"'
export FZF_DEFAULT_OPTS='
  --height 40%
  --layout=reverse
  --border
  --preview "bat --color=always --style=numbers --line-range=:500 {}"
'

~/.bashrc,之后 Ctrl-T 直接带预览。

fzf + Neovim

最快的"在 vim 里 fuzzy 找文件":

" init.lua / vimrc
nnoremap <leader>f :Telescope find_files<cr>   " telescope 已经是 fzf-like

或装 fzf.vim

nnoremap <leader>f :FZF<cr>

多选 + 操作

# 多选文件批量删除
rm $(fzf -m)

# 多选 git commit 做 cherry-pick
git cherry-pick $(git log --oneline | fzf -m | awk '{print $1}')

-m 启用 multi-select;用 Tab 选中 / 取消选中。

自定义 preview

# 选目录,右边显示 ls
find . -type d | fzf --preview 'ls -la {}'

# 选 PR 号,右边显示 PR 详情
gh pr list | fzf --preview 'gh pr view {1}' | awk '{print $1}'

模糊语法

  • 默认 fzf 用 "smart case + fuzzy":你打 usrlist 能匹配 User_List_View.tsx
  • 'word:精确匹配
  • ^prefix:开头
  • suffix$:结尾
  • !noword:取反
  • word1 | word2:或

自定义颜色

export FZF_DEFAULT_OPTS='
  --color=bg+:#313244,bg:#1e1e2e,spinner:#f5e0dc,hl:#f38ba8
  --color=fg:#cdd6f4,header:#f38ba8,info:#cba6f7,pointer:#f5e0dc
  --color=marker:#f5e0dc,fg+:#cdd6f4,prompt:#cba6f7,hl+:#f38ba8
'

Catppuccin Mocha 主题。其他主题:fzf 的 wiki 一大堆。

把 fzf 放进生产脚本

#!/usr/bin/env bash
# deploy.sh - 选要部署的版本
TAG=$(git tag | sort -rV | fzf --header='选要部署的版本') || exit 1
echo "Deploying $TAG..."
ssh prod-server "cd /srv/app && git fetch && git checkout $TAG && systemctl restart app"

CI 里 fzf 没意义(无 tty),但本地交互式脚本用 fzf 比一堆 case 语句
干净得多。

踩过的坑

  • 嵌套 fzf(fzf 选完结果当 fzf 参数)容易卡住——子 fzf 进程被父 fzf
    抢 tty。中间存个变量再调用。
  • FZF_DEFAULT_COMMAND 设了 rg 但 rg 没装:所有 fzf 调用都报错。
    确保 rg / fd 都装了。
  • 大目录(node_modules、.cache)拖慢 fzf:默认 command 加 --glob '!**/node_modules'
    之类排除。fd 比 find 快 5-10 倍且默认尊重 .gitignore。
  • WSL 里 fzf 偶尔光标错位,是终端 escape sequence 问题;升级 Windows Terminal
  • 用最新 fzf 解决。
精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。