40 KiB
Note
本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
English · 原始项目 · 上游 README
原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。
表达对 fzf 的喜爱——T 恤、马克杯和贴纸现已上架!
commitgoods.com/collections/fzf
fzf 是一款通用命令行模糊查找器(fuzzy finder)和交互式终端工具包。
无论你是选择文件、浏览命令历史、预览数据、 通过模糊匹配浏览复杂数据集,还是创建自定义菜单和 工作流,fzf 都提供了将 shell 脚本转变为丰富 终端应用所需的构建模块。
亮点
- 便携 // 以单一二进制文件分发,便于安装
- 快速 // 经过优化,可在毫秒内处理数百万条目
- 可编程 // 事件驱动架构,用于构建自定义终端界面和工作流
- 开箱即用 // 内置与 Bash、Zsh、Fish、Nushell、Vim 和 Neovim 的集成
目录
安装
使用 Homebrew
你可以使用 Homebrew(在 macOS 或 Linux 上)安装 fzf。
brew install fzf
Important
要配置 shell 集成(快捷键和模糊补全), 请参阅下方说明。
fzf 也可通过 MacPorts 获取:sudo port install fzf
使用 Mise
你可以使用 mise 安装 fzf。
mise use -g fzf@latest
Linux 软件包
| 软件包管理器 | Linux 发行版 | 命令 |
|---|---|---|
| APK | Alpine Linux | sudo apk add fzf |
| APT | Debian 9+/Ubuntu 19.10+ | sudo apt install fzf |
| Conda | conda install -c conda-forge fzf |
|
| DNF | Fedora | sudo dnf install fzf |
| Nix | NixOS, etc. | nix-env -iA nixpkgs.fzf |
| Pacman | Arch Linux | sudo pacman -S fzf |
| pkg | FreeBSD | pkg install fzf |
| pkgin | NetBSD | pkgin install fzf |
| pkg_add | OpenBSD | pkg_add fzf |
| Portage | Gentoo | emerge --ask app-shells/fzf |
| Spack | spack install fzf |
|
| XBPS | Void Linux | sudo xbps-install -S fzf |
| Zypper | openSUSE | sudo zypper install fzf |
Important
要配置 shell 集成(快捷键和模糊补全), 请参阅下方说明。
Windows 软件包
在 Windows 上,可通过 Chocolatey、Scoop、 Winget 和 MSYS2 安装 fzf:
| 软件包管理器 | 命令 |
|---|---|
| Chocolatey | choco install fzf |
| Scoop | scoop install fzf |
| Winget | winget install fzf |
| MSYS2 (pacman) | pacman -S $MINGW_PACKAGE_PREFIX-fzf |
使用 git
或者,你可以将此仓库 "git clone" 到任意目录,然后运行 安装 脚本。
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
安装脚本会向你的 shell 配置文件中添加行,以修改
$PATH 并设置 shell 集成。
二进制发布版
你可以从发布页面下载官方的 fzf 二进制文件。
设置 shell 集成
将以下行添加到你的 shell 配置文件中。
- bash
# 设置 fzf 快捷键和模糊补全 eval "$(fzf --bash)" - zsh
# 设置 fzf 快捷键和模糊补全 source <(fzf --zsh) - fish
# 设置 fzf 快捷键 fzf --fish | source - Nushell——Nushell 不支持将内容管道到
source,因此安装 脚本会在自动加载目录中生成一个文件。如果你没有使用安装脚本,可以手动设置:# 生成集成脚本 mkdir ($nu.default-config-dir | path join "autoload") fzf --nushell | save -f ($nu.default-config-dir | path join "autoload" "_fzf_integration.nu")
Note
--bash、--zsh、--fish和--nushell选项仅适用于 较新版本的 fzf。如果你使用较旧版本的 fzf,或希望进行更精细的控制,可以 引用 /shell 目录中的各个脚本文件。这些 文件的位置可能因你所用的包管理器而异。 请参阅包文档以获取更多信息。 (例如apt show fzf)
Tip
你可以通过在引用脚本时,将对应的
*_COMMAND变量设为空字符串来禁用 CTRL-T、CTRL-R 或 ALT-C 快捷键。例如,禁用 CTRL-R 和 ALT-C:
- bash:
FZF_CTRL_R_COMMAND= FZF_ALT_C_COMMAND= eval "$(fzf --bash)"- zsh:
FZF_CTRL_R_COMMAND= FZF_ALT_C_COMMAND= source <(fzf --zsh)- fish:
fzf --fish | FZF_CTRL_R_COMMAND= FZF_ALT_C_COMMAND= source- nushell:在你的
env.nu中添加:$env.FZF_CTRL_R_COMMAND = ""; $env.FZF_ALT_C_COMMAND = ""在引用脚本之后设置变量将不会生效。
Vim/Neovim 插件
如果你使用 vim-plug,),请将以下内容添加到 你的 Vim 配置文件中:
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
junegunn/fzf提供基础库函数fzf#install()确保你拥有最新二进制文件
junegunn/fzf.vim是一个独立项目), 提供各种有用的命令
要了解更多关于 Vim 集成的信息,请参阅 README-VIM.md。
Tip
如果你使用 Neovim 并偏好基于 Lua 的插件,请查看 fzf-lua.)
升级 fzf
fzf 正在积极开发中,你可能需要时不时地升级它。请根据你使用的安装方式 按照以下说明操作。
- git:
cd ~/.fzf && git pull && ./install - brew:
brew update; brew upgrade fzf - macports:
sudo port upgrade fzf - chocolatey:
choco upgrade fzf - vim-plug:
:PlugUpdate fzf
构建 fzf
请参阅 BUILD.md。
用法
fzf 会启动交互式查找器,从 STDIN 读取列表,并将选中的项目写入 STDOUT。
find * -type f | fzf > selected
没有 STDIN 管道时,fzf 会遍历当前目录下的文件系统来获取文件列表。
vim $(fzf)
Note
你可以覆盖默认行为
- 要么将
$FZF_DEFAULT_COMMAND设置为一个生成所需列表的命令- 要么在
$FZF_DEFAULT_OPTS中设置--walker、--walker-root和--walker-skip选项
Warning
更稳健的解决方案是使用
xargs,但我们展示 了上述方案,因为它更容易理解fzf --print0 | xargs -0 -o vim
Tip
fzf 还能够将自身转换为另一个进程。
fzf --bind 'enter:become(vim {})'有关更多信息,请参阅转换为另一个进程。
使用查找器
CTRL-K/CTRL-J(或CTRL-P/CTRL-N)上下移动光标Enter键选择项目,CTRL-C/CTRL-G/ESC退出- 多选模式(
-m)下,使用TAB和Shift-TAB标记多个项目 - Emacs 风格快捷键
- 鼠标:滚动、单击、双击;多选模式下 shift+单击 和 shift+滚动
显示模式
fzf 默认以全屏模式运行,但也有其他显示模式。
--height 模式
使用 --height HEIGHT[%],fzf 将在光标下方以指定高度启动。
fzf --height 40%
reverse 布局和 --border 与此选项搭配效果良好。
fzf --height 40% --layout reverse --border
在高度前加上 ~,可以设置最大高度。
# Will take as few lines as possible to display the list
seq 3 | fzf --height ~100%
seq 3000 | fzf --height ~100%
高度值可以是负数。
# Screen height - 3
fzf --height -3
--popup 模式
使用 --popup 选项,fzf 将在弹出窗口中启动
(需要 tmux 3.3+ 或 Zellij 0.44+)。
# --popup [center|top|bottom|left|right][,SIZE[%]][,SIZE[%][,border-native]]
fzf --popup center # Center, 50% width and height
fzf --popup 80% # Center, 80% width and height
fzf --popup 100%,50% # Center, 100% width and 50% height
fzf --popup left,40% # Left, 40% width
fzf --popup left,40%,90% # Left, 40% width, 90% height
fzf --popup top,40% # Top, 40% height
fzf --popup bottom,80%,40% # Bottom, 80% width, 40% height
当你不处于 tmux 或 Zellij 环境中时,--popup 会被静默忽略。
Note
如果你使用的是不支持弹出窗口的旧版 tmux, 或者你想在常规 tmux 窗格中打开 fzf,请查看 fzf-tmux 脚本。
Tip
你可以将这些选项添加到
$FZF_DEFAULT_OPTS中,以便默认应用它们。 例如,# 如果在 tmux 或 Zellij 中则在弹出窗口中打开,否则使用 --height 模式 export FZF_DEFAULT_OPTS='--height 40% --popup bottom,40% --layout reverse --border top'
搜索语法
除非另有指定,fzf 以"扩展搜索模式"启动,你可以输入多个以空格分隔的搜索词。例如 ^music .mp3$ sbtrkt !fire
| 标记 | 匹配类型 | 描述 |
|---|---|---|
sbtrkt |
模糊匹配 | 匹配 sbtrkt 的项目 |
'wild |
精确匹配(带引号) | 包含 wild 的项目 |
'wild' |
精确边界匹配(两端均带引号) | 在单词边界处包含 wild 的项目 |
^music |
前缀精确匹配 | 以 music 开头的项目 |
.mp3$ |
后缀精确匹配 | 以 .mp3 结尾的项目 |
!fire |
反向精确匹配 | 不包含 fire 的项目 |
!^music |
反向前缀精确匹配 | 不以 music 开头的项目 |
!.mp3$ |
反向后缀精确匹配 | 不以 .mp3 结尾的项目 |
如果你不喜欢模糊匹配且不希望给每个词加引号,
请使用 -e 或 --exact 选项启动 fzf。注意,当设置了
--exact 时,' 前缀会"取消引号"该词条。
单个竖线字符词条充当 OR 运算符。例如,以下查询匹配以 core 开头
且以 go、rb 或 py 结尾的条目。
^core go$ | rb$ | py$
环境变量
FZF_DEFAULT_COMMAND- 当输入为 tty 时使用的默认命令
- 例如
export FZF_DEFAULT_COMMAND='fd --type f'
FZF_DEFAULT_OPTS- 默认选项
- 例如
export FZF_DEFAULT_OPTS="--layout=reverse --inline-info"
FZF_DEFAULT_OPTS_FILE- 如果你更倾向于在文件中管理默认选项,请将此变量设置为 指向该文件的位置
- 例如
export FZF_DEFAULT_OPTS_FILE=~/.fzfrc
Warning
FZF_DEFAULT_COMMAND未被 shell 集成使用,因为需求略有差异。
CTRL-T运行$FZF_CTRL_T_COMMAND以获取文件和目录列表ALT-C运行$FZF_ALT_C_COMMAND以获取目录列表vim ~/**<tab>以前缀(~/)作为第一个参数运行fzf_compgen_path()cd foo**<tab>以前缀(foo)作为第一个参数运行fzf_compgen_dir()可用选项详见本文档后续内容。
自定义外观
fzf 的用户界面可通过大量配置选项进行完全自定义。如需快速设置,你可以使用 default、full 或 minimal 等样式预设之一,通过 --style 选项启动。
fzf --style full \
--preview 'fzf-preview.sh {}' --bind 'focus:transform-header:file --brief {}'
| 预设 | 截图 |
|---|---|
default |
![]() |
full |
![]() |
minimal |
![]() |
以下是一个基于 full 预设的示例:
git ls-files | fzf --style full \
--border --padding 1,2 \
--border-label ' Demo ' --input-label ' Input ' --header-label ' File Type ' \
--preview 'fzf-preview.sh {}' \
--bind 'result:transform-list-label:
if [[ -z $FZF_QUERY ]]; then
echo " $FZF_MATCH_COUNT items "
else
echo " $FZF_MATCH_COUNT matches for [$FZF_QUERY] "
fi
' \
--bind 'focus:transform-preview-label:[[ -n {} ]] && printf " Previewing [%s] " {}' \
--bind 'focus:+transform-header:file --brief {} || echo "No file selected"' \
--bind 'ctrl-r:change-list-label( Reloading the list )+reload(sleep 2; git ls-files)' \
--color 'border:#aaaaaa,label:#cccccc' \
--color 'preview-border:#9999cc,preview-label:#ccccff' \
--color 'list-border:#669966,list-label:#99cc99' \
--color 'input-border:#996666,input-label:#ffcccc' \
--color 'header-border:#6699cc,header-label:#99ccff'
选项
请查阅手册(fzf --man 或 man fzf)获取完整选项列表。
演示
如果你喜欢通过视频学习,可以观看 @samoshkin) 制作的这个录屏,探索 fzf 的各项功能。
示例
- 示例 Wiki 页面)
- 免责声明:该页面上的示例由社区维护,未经全面测试
- 高级 fzf 示例)
命令行按键绑定
通过设置 shell 集成,你可以在 bash、zsh、fish 和 Nushell 中使用以下按键绑定。
CTRL-T- 将选中的文件和目录粘贴到命令行中- 列表通过
--walker file,dir,follow,hidden选项生成- 你可以通过设置
FZF_CTRL_T_COMMAND为自定义命令来覆盖默认行为 - 或者你可以在
FZF_CTRL_T_OPTS中设置--walker*选项
- 你可以通过设置
- 设置
FZF_CTRL_T_OPTS以向 fzf 传递额外选项# 使用 bat 预览文件内容(https://github.com/sharkdp/bat)) export FZF_CTRL_T_OPTS=" --walker-skip .git,node_modules,target --preview 'bat -n --color=always {}' --bind 'ctrl-/:change-preview-window(down|hidden|)'" - 可以通过在加载脚本时将
FZF_CTRL_T_COMMAND设为空字符串来禁用
- 列表通过
CTRL-R- 将选中的历史命令粘贴到命令行中。- 使用
TAB选择多条命令。 - 如果想按时间顺序查看命令,再次按下
CTRL-R可切换为按相关性排序 - 按下
ALT-R切换"原始"模式,可查看匹配项周围的上下文。在该模式下,按下CTRL-N和CTRL-P仅在匹配项之间移动。 - 按下
CTRL-/或ALT-/切换自动换行 - 按下
SHIFT-DELETE删除选中的命令(bash 和 fish) - 仅限 Fish shell:
- 按下
ALT-ENTER重新格式化并插入选中的命令 - 按下
ALT-T循环切换命令前缀(时间戳、日期/时间、无)
- 按下
- 设置
FZF_CTRL_R_OPTS以向 fzf 传递额外选项# CTRL-Y 使用 pbcopy 将命令复制到剪贴板 export FZF_CTRL_R_OPTS=" --bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort' --color header:italic --header 'Press CTRL-Y to copy command into clipboard'"# Fish shell:设置日期/时间为默认前缀 set -gx FZF_CTRL_R_OPTS "--with-nth 1,3.. --bind 'alt-t:change-with-nth(2..|3..|1,3..)'" # 或默认不显示前缀 set -gx FZF_CTRL_R_OPTS "--with-nth 3.. --bind 'alt-t:change-with-nth(2..|1,3..|3..)'" - 可以通过在加载脚本时将
FZF_CTRL_R_COMMAND设为空字符串来禁用 - 通过非空的
FZF_CTRL_R_COMMAND进行自定义覆盖暂不支持,会发出警告
- 使用
ALT-C- 进入选中的目录- 列表通过
--walker dir,follow,hidden选项生成 - 设置
FZF_ALT_C_COMMAND以覆盖默认命令- 或者你可以在
FZF_ALT_C_OPTS中设置--walker-*选项
- 或者你可以在
- 设置
FZF_ALT_C_OPTS以向 fzf 传递额外选项# 在预览窗口中打印树形结构 export FZF_ALT_C_OPTS=" --walker-skip .git,node_modules,target --preview 'tree -C {}'" - 可以通过在加载脚本时将
FZF_ALT_C_COMMAND设为空字符串来禁用
- 列表通过
这些绑定的显示模式可通过 FZF_{CTRL_T,CTRL_R,ALT_C}_OPTS 单独配置,或通过 FZF_DEFAULT_OPTS 全局配置。
(例如:FZF_CTRL_R_OPTS='--popup bottom,60% --height 60% --border top')
更多技巧请参见 Wiki 页面.)
模糊补全
Shell 集成还为 bash、zsh、fish 和 Nushell 提供了模糊补全功能。
文件和目录
如果光标前的单词以触发序列结尾(默认为 **),则可触发文件和目录的模糊补全。
COMMAND [DIRECTORY/][FUZZY_PATTERN]**<TAB>
# Files under the current directory
# - You can select multiple items with TAB key
vim **<TAB>
# Files under parent directory
vim ../**<TAB>
# Files under parent directory that match `fzf`
vim ../fzf**<TAB>
# Files under your home directory
vim ~/**<TAB>
# Directories under current directory (single-selection)
cd **<TAB>
# Directories under ~/github that match `fzf`
cd ~/github/fzf**<TAB>
进程 ID
为 kill 命令提供了 PID 的模糊补全。
# Can select multiple processes with <TAB> or <Shift-TAB> keys
kill -9 **<TAB>
主机名
为 ssh 命令提供了主机名的模糊补全。主机名从 /etc/hosts 和 ~/.ssh/config 中提取。
ssh **<TAB>
环境变量 / 别名
# bash and zsh
unset **<TAB>
export **<TAB>
unalias **<TAB>
# fish
set <SHIFT-TAB>
自定义 bash 和 zsh 的模糊补全
自定义补全的 fzf 选项
# Use ~~ as the trigger sequence instead of the default **
export FZF_COMPLETION_TRIGGER='~~'
# Options to fzf command
export FZF_COMPLETION_OPTS='--border --info=inline'
# Options for path completion (e.g. vim **<TAB>)
export FZF_COMPLETION_PATH_OPTS='--walker file,dir,follow,hidden'
# Options for directory completion (e.g. cd **<TAB>)
export FZF_COMPLETION_DIR_OPTS='--walker dir,follow'
# Advanced customization of fzf options via _fzf_comprun function
# - The first argument to the function is the name of the command.
# - You should make sure to pass the rest of the arguments ($@) to fzf.
_fzf_comprun() {
local command=$1
shift
case "$command" in
cd) fzf --preview 'tree -C {} | head -200' "$@" ;;
export|unset) fzf --preview "eval 'echo \$'{}" "$@" ;;
ssh) fzf --preview 'dig {}' "$@" ;;
*) fzf --preview 'bat -n --color=always {}' "$@" ;;
esac
}
自定义路径和目录的补全来源
# Use fd (https://github.com/sharkdp/fd) for listing path candidates.
# - The first argument to the function ($1) is the base path to start traversal
# - See the source code (completion.{bash,zsh}) for the details.
_fzf_compgen_path() {
fd --hidden --follow --exclude ".git" . "$1"
}
# Use fd to generate the list for directory completion
_fzf_compgen_dir() {
fd --type d --hidden --follow --exclude ".git" . "$1"
}
支持的命令(bash)
在 bash 中,模糊补全仅对预定义的命令集生效
(可通过 complete | grep _fzf 查看列表)。但你也可以使用
_fzf_setup_completion 辅助函数为其他命令启用模糊补全。
# usage: _fzf_setup_completion path|dir|var|alias|host COMMANDS...
_fzf_setup_completion path ag git kubectl
_fzf_setup_completion dir tree
自定义模糊补全
(自定义补全 API 处于实验阶段,可能发生变更)
对于名为 "COMMAND" 的命令,使用 _fzf_complete 辅助函数定义
_fzf_complete_COMMAND 函数。
# Custom fuzzy completion for "doge" command
# e.g. doge **<TAB>
_fzf_complete_doge() {
_fzf_complete --multi --reverse --prompt="doge> " -- "$@" < <(
echo very
echo wow
echo such
echo doge
)
}
--之前的参数是传递给 fzf 的选项。--之后,只需原封不动地传递原始的补全参数("$@")。- 然后,编写一组命令来生成补全候选,并通过进程替换(
< <(...)) 将其输出送入该函数。
zsh 会根据命名约定自动识别该函数,但在 bash 中,你需要使用
complete 命令手动将函数与命令关联。
[ -n "$BASH" ] && complete -F _fzf_complete_doge -o default -o bashdefault doge
如果你需要对 fzf 的输出进行后处理,可以按如下方式定义
_fzf_complete_COMMAND_post。
_fzf_complete_foo() {
_fzf_complete --multi --reverse --header-lines=3 -- "$@" < <(
ls -al
)
}
_fzf_complete_foo_post() {
awk '{print $NF}'
}
[ -n "$BASH" ] && complete -F _fzf_complete_foo -o default -o bashdefault foo
Fish 的模糊补全
Fish 的模糊补全与 bash 和 zsh 的区别在于:
- 它不需要像
**这样的触发序列。相反,它在Shift-TAB上激活(替代原生分页器搜索模式),而TAB保留 fish 的原生补全行为。 - 它依赖 fish 的原生补全系统来生成候选列表,而非执行递归的文件系统遍历。如需递归搜索,
请改用
CTRL-T绑定。 - 如果当前命令行令牌是通配符模式,它会在通配符展开路径列表上执行搜索(而非将 所有结果插入命令行的原生行为)。由于展开由 shell 执行,结果数量存在上限。
- 仅支持的配置变量是
FZF_COMPLETION_OPTS和FZF_EXPANSION_OPS。 - 自定义补全函数所使用的函数名为
fzf_complete,它只接受 fzf 选项作为参数,也可以在没有任何重定向输入的情况下调用, 仅用于修改 fzf 选项同时呈现原生补全结果。为了与其他 shell 兼容, 提供了名为_fzf_complete的函数,它在 fzf 选项之后可以接受命令行参数中的-- $argv。
对于 fish 补全覆盖不到的命令,最好创建常规的 fish 补全函数(这对 TAB 和
Shift-TAB 都有效),并仅在需要修改特定命令的 fzf 选项或希望 Shift-TAB
获得不同结果时才创建 fzf 补全函数:
# Customize git completion
function _fzf_complete_git
# Show header text with active branch for all git completions
set -lx -- FZF_COMPLETION_OPTS --header="'"(git branch --show-current 2>/dev/null)"'"
# No other changes when less than 3 arguments, or when completing options
if not set -q argv[3]; or string match -q -- '-*' $argv[-1]
fzf_complete
return
end
# Check subcommand
switch $argv[2]
case checkout diff log show
# Set preview and display all branches and commits for subcommands: checkout, diff, log, show
begin
git branch --all --format='%(refname:short)'
git log --all --oneline --color=always
end | fzf_complete --no-multi --ansi --accept-nth=1 --query=$argv[-1] --preview='git show --color=always {1}'
case add rm mv
# Only set preview for subcommands: add, rm, mv
# Special characters in fish completion lists are escaped, so the r flag must be used.
fzf_complete --preview="git diff --color=always {r1}"
case '*'
# No changes for other subcommands
fzf_complete
end
end
与 bash 和 zsh 类似,可以通过定义一个名为 _fzf_complete_COMMAND_post 或
_fzf_post_complete_COMMAND 的函数来对 fzf 的输出进行处理后再插入命令行:
function _fzf_complete_foo
ls -sh --zero --color=always | fzf_complete --read0 --print0 --ansi --no-multi-line --header-lines=1
end
function _fzf_post_complete_foo
while read -lz result
string escape -n -- $result | string trim -l -c '\ ' | string split -m 1 -f 2 ' '
end
end
Nushell 的模糊补全
Nushell 中的模糊补全通过 外部补全器) 机制实现。与 bash 和 zsh 相比存在一些差异:
- 在 Nushell >= 0.103.0 上,内置命令(例如
cd、ls)不再调用外部补全器。使用**<TAB>的模糊补全仅对外部命令生效。 - 自定义补全器可以通过
$env.FZF_COMPLETERS记录在你的config.nu中定义。每个条目是一个闭包,接收前缀和命令跨度,返回候选字符串列表或包含自定义 fzf 选项的记录{ candidates: [...], opts: [...] }:更多示例请参见 shell/completion-examples.nu。$env.FZF_COMPLETERS = { pacman: {|prefix, spans| let sub = $spans | skip 1 | first let candidates = (if ($sub =~ "-[SF]") { ^pacman -Slq | lines } else if ($sub =~ "-[QR]") { ^pacman -Qq | lines } else { [] }) { candidates: $candidates, opts: ["--preview", "pacman -Si {}"] } } } - 支持以下环境变量:
FZF_COMPLETION_TRIGGER、FZF_COMPLETION_OPTS、FZF_COMPLETION_PATH_OPTS、FZF_COMPLETION_DIR_OPTS、FZF_COMPLETION_DIR_COMMANDS。
Vim 插件
参见 README-VIM.md。
高级主题
针对不同类型输入的自定义
由于 fzf 是一个通用的文本过滤器,其算法设计为"一般"能很好地适用于任何类型的输入。但不可否认,没有真正通用的解决方案,你可能需要根据输入类型调整算法和一些设置。为简化这一过程,fzf 为几种常见输入类型提供了一套"方案"。
| 方案 | 描述 |
|---|---|
--scheme=default |
通用方案,设计为能很好地适用于任何类型的输入 |
--scheme=path |
适用于文件路径 |
--scheme=history |
适用于命令历史或任何按时间顺序排列重要的输入 |
(详见 fzf --man)
性能
fzf 很快。在大多数使用场景中性能不应成为问题。不过,你可能需要注意那些会影响性能的选项。
--ansi告知 fzf 提取并解析输入中的 ANSI 颜色代码,这会使初始扫描变慢。因此不建议将其加入$FZF_DEFAULT_OPTS。--nth会使 fzf 变慢,因为它需要对每一行进行分词。- 纯字符串
--delimiter应优先于正则表达式分隔符。 --with-nth会使 fzf 变慢,因为它需要对每一行进行分词并重新组装。
执行外部程序
你可以设置按键绑定,在不离开 fzf 的情况下启动外部进程(execute、execute-silent)。
# Press F1 to open the file with less without leaving fzf
# Press CTRL-Y to copy the line to clipboard and aborts fzf (requires pbcopy)
fzf --bind 'f1:execute(less -f {}),ctrl-y:execute-silent(echo {} | pbcopy)+abort'
详情请参阅手册的按键/事件绑定章节。
切换为另一个进程
become(...) 与上文介绍的 execute(...)/execute-silent(...) 类似,不同之处在于它不会执行命令后返回 fzf,而是将 fzf 切换为执行该命令的新进程。
fzf --bind 'enter:become(vim {})'
与看似等效的命令替换 vim "$(fzf)" 相比,这种方式有几个优势:
- 当用 CTRL-C 终止 fzf 时,Vim 不会打开空文件
- 当在空结果上按 ENTER 时,Vim 不会打开空文件
- 可以处理多项选择,即使其中包含空格
fzf --multi --bind 'enter:become(vim {+})'
公平地说,使用 fzf --print0 | xargs -0 -o vim 代替 vim "$(fzf)" 可以解决上述所有问题。尽管如此,become(...) 在不同场景下仍提供了额外优势。
- 你可以设置多个绑定,以不同方式处理结果,而无需任何包装脚本
fzf --bind 'enter:become(vim {}),ctrl-e:become(emacs {})'- 之前,你需要使用
--expect=ctrl-e并检查 fzf 输出的第一行
- 之前,你需要使用
- 你可以利用 fzf 的字段索引表达式轻松构建后续命令
# 在 Vim 中打开文件并跳转到指定行 git grep --line-number . | fzf --delimiter : --nth 3.. --bind 'enter:become(vim {1} +{2})'
重新加载候选列表
通过将 reload 操作绑定到某个按键或事件,你可以让 fzf 动态重新加载候选列表。详情请参见 https://github.com/junegunn/fzf/issues/1750。
1. 按 CTRL-R 更新进程列表
ps -ef |
fzf --bind 'ctrl-r:reload(ps -ef)' \
--header 'Press CTRL-R to reload' --header-lines=1 \
--height=50% --layout=reverse
2. 按 CTRL-D 或 CTRL-F 切换源
FZF_DEFAULT_COMMAND='find . -type f' \
fzf --bind 'ctrl-d:reload(find . -type d),ctrl-f:reload(eval "$FZF_DEFAULT_COMMAND")' \
--height=50% --layout=reverse
3. 交互式 ripgrep 集成
以下示例将 fzf 作为 ripgrep 的选择器界面。我们将 reload 操作绑定到 change 事件,这样每当你在 fzf 中输入时,ripgrep 进程都会重新启动,并使用占位符表达式 {q} 表示更新后的查询字符串。另外,注意我们使用了 --disabled 选项,使 fzf 不执行任何二次过滤。
: | rg_prefix='rg --column --line-number --no-heading --color=always --smart-case' \
fzf --bind 'start:reload:$rg_prefix ""' \
--bind 'change:reload:$rg_prefix {q} || true' \
--bind 'enter:become(vim {1} +{2})' \
--ansi --disabled \
--height=50% --layout=reverse
如果 ripgrep 没有找到任何匹配项,它将以非零退出码退出,fzf 会对此发出警告。要抑制该警告信息,我们为命令添加了 || true,使其始终以 0 退出。
更复杂的示例请参见 "Using fzf as interactive Ripgrep launcher"`)。
预览窗口
设置 --preview 选项后,fzf 会自动启动一个外部进程,将当前行作为参数传入,并在拆分窗口中显示结果。你的 $SHELL 用于执行该命令,$SHELL -c COMMAND 作为参数传入。可以使用鼠标或自定义按键绑定来滚动窗口。
# {} is replaced with the single-quoted string of the focused line
fzf --preview 'cat {}'
预览窗口支持 ANSI 颜色,因此你可以使用任何能够对文件内容进行语法高亮的程序,例如 Bat) 或 [Highlight](https://gitlab.com/saalen/highlight):`)。
fzf --preview 'bat --color=always {}' --preview-window '~3'
你可以使用 --preview-window 选项自定义预览窗口的大小、位置和边框,使用 --color 选项自定义其前景色和背景色。例如:
fzf --height 40% --layout reverse --info inline --border \
--preview 'file {}' --preview-window up,1,border-horizontal \
--bind 'ctrl-/:change-preview-window(50%|hidden|)' \
--color 'fg:#bbccdd,fg+:#ddeeff,bg:#334455,preview-bg:#223344,border:#778899'
完整选项列表请参阅手册(man fzf)。
更多高级示例请参见此处.`)。
Warning
由于 fzf 是通用文本过滤器而非文件查找器,不建议将
--preview选项加入你的$FZF_DEFAULT_OPTS。# ********************* # ** 不要这样做!** # ********************* export FZF_DEFAULT_OPTS='--preview "bat --style=numbers --color=always --line-range :500 {}"' # bat 不适用于除文件列表以外的任何输入 ps -ef | fzf seq 100 | fzf history | fzf
预览图片
fzf 可以通过以下协议之一在预览窗口中显示图片:
- Kitty 图形协议`)
- iTerm2 内联图片协议`)
- Sixel`)
更多信息请参见 bin/fzf-preview.sh 脚本。
fzf --preview 'fzf-preview.sh {}'
技巧
遵守 .gitignore
你可以使用 fd,)、[ripgrep](https://github.com/BurntSushi/ripgrep),) 或 [The Silver Searcher](https://github.com/ggreer/the_silver_searcher)`) 来遍历文件系统,同时遵守 .gitignore。
# Feed the output of fd into fzf
fd --type f --strip-cwd-prefix | fzf
# Setting fd as the default source for fzf
export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix'
# Now fzf (w/o pipe) will use the fd command to generate the list
fzf
# To apply the command to CTRL-T as well
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
如果你希望命令跟随符号链接且不排除隐藏文件,请使用以下命令:
export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix --hidden --follow --exclude .git'
Fish shell
与 bash 和 zsh 不同,fish 的 CTRL-T 按键绑定会将命令行上的最后一个 token 作为递归搜索的根目录。例如,在以下命令行的末尾按下 CTRL-T:
ls /var/
将列出 /var/ 下的所有文件和目录。
使用自定义 FZF_CTRL_T_COMMAND 时,请使用未展开的 $dir 变量来利用此功能。当最后一个 token 不是有效目录时,$dir 默认为 .。示例:
set -g FZF_CTRL_T_COMMAND "command find -L \$dir -type f 2> /dev/null | sed '1d; s#^\./##'"
fzf 主题游乐场
fzf 主题游乐场) 由 [Vitor Mello](https://github.com/vitormv)`) 创建,是一个可以交互式创建 fzf 主题的网页。
相关项目
https://github.com/junegunn/fzf/wiki/Related-projects
License
MIT 许可证 (MIT)
Copyright (c) 2013-2026 Junegunn Choi
Goods
在此获取 fzf T 恤、马克杯和贴纸:https://commitgoods.com/collections/fzf
Sponsors ❤️
我要感谢本项目的所有赞助商,是他们让我能够继续改进 fzf。
如果你想赞助本项目,请访问 https://github.com/sponsors/junegunn.



