🌸 一个命令行的模糊搜索器
作者:Sec-Labs | 发布时间:
项目地址
https://github.com/junegunn/fzf
fzf 是一个通用的命令行模糊查找器。

它是一个用于命令行的交互式 Unix 过滤器,可以与任何列表一起使用; 文件、命令历史记录、进程、主机名、书签、git 提交等。
优点
- 便携,无依赖
- 快如闪电
- 最全面的功能集
- 灵活的布局
- 包括电池
- Vim/Neovim 插件、键绑定和模糊自动完成
目录
安装
fzf 项目由以下组件组成:
fzf可执行的fzf-tmux在 tmux 窗格中启动 fzf 的脚本- 外壳扩展
- 键绑定(
CTRL-T、CTRL-R和ALT-C)(bash、zsh、fish) - 模糊自动补全 (bash, zsh)
- 键绑定(
- Vim/Neovim 插件
如果您不需要额外的东西, 您可以单独 下载 fzf 可执行文件。
使用自制软件
您可以使用 Homebrew (在 macOS 或 Linux 上)安装 fzf。
brew install fzf
# To install useful key bindings and fuzzy completion:
$(brew --prefix)/opt/fzf/install
fzf 也可以 通过 MacPorts 获得: sudo port install fzf
使用混帐
或者,您可以将此存储库“git clone”到任何目录并运行 安装 脚本。
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
使用 Linux 包管理器
| 包管理器 | Linux 发行版 | 命令 |
|---|---|---|
| APK | Alpine Linux | sudo apk add fzf |
| APT | Debian 9+/Ubuntu 19.10+ | sudo apt-get 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 | Void Linux | pkg_add fzf |
| XBPS | openSUSE | sudo xbps-install -S fzf |
| 赛珀 | 开放SUSE | sudo zypper install fzf |
⚠️ 默认情况下可能不启用键绑定 (CTRL-T / CTRL-R / ALT-C) 和模糊自动完成。
有关详细信息,请参阅包文档。 (例如
apt-cache show fzf)
视窗
可以在此处 下载适用于 Windows 的预构建二进制文件 。 fzf 也可以通过 Chocolatey 和 Scoop 获得:
| 包管理器 | 命令 |
|---|---|
| Chocolatey | choco install fzf |
| Scoop | scoop install fzf |
可以在 wiki 页面 上找到 Windows 上的已知问题和限制。
作为 Vim 插件
如果您使用 vim-plug ,请将此行添加到您的 Vim 配置文件中:
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
fzf#install() 确保您拥有最新的二进制文件,但它是可选的,因此如果您使用不支持挂钩的插件管理器,则可以省略它。
有关更多安装选项,请参阅 README-VIM.md 。
升级 fzf
fzf 正在积极开发中,您可能希望偶尔升级它。 请根据使用的安装方法按照以下说明进行操作。
- 混帐:
cd ~/.fzf && git pull && ./install - 酿造:
brew update; brew upgrade fzf - 麦克波特:
sudo port upgrade fzf - 巧克力味的:
choco upgrade fzf - vim插件:
:PlugUpdate fzf
建设fzf
参见 BUILD.md 。
用法
fzf 将启动交互式查找器,从 STDIN 读取列表,并将所选项目写入 STDOUT。
find * -type f | fzf > selected
如果没有 STDIN 管道,fzf 将使用 find 命令获取不包括隐藏文件的文件列表。 (您可以使用覆盖默认命令 FZF_DEFAULT_COMMAND )
vim $(fzf)
使用取景器
CTRL-K/CTRL-J(或CTRL-P/CTRL-N)上下移动光标Enter键选择项目,CTRL-C/CTRL-G/ESC退出- 在多选模式 (
-m) 上,TAB并Shift-TAB标记多个项目 - Emacs 样式键绑定
- 鼠标:滚动、单击、双击; shift-click 和 shift-scroll 在多选模式下
布局
默认情况下,fzf 以全屏模式启动,但您可以使用 --height 选项使其在光标下方启动。
vim $(fzf --height 40%)
此外,如果您更喜欢“自上而下”布局而不是默认的“自下而上”布局 ,请查看 --reverse 和选项。 --layout
vim $(fzf --height 40% --reverse)
您可以将这些选项添加到, $FZF_DEFAULT_OPTS 以便默认应用它们。 例如,
export FZF_DEFAULT_OPTS='--height 40% --layout=reverse --border'
搜索语法
除非另有说明,否则 fzf 以“扩展搜索模式”启动,您可以在其中输入多个由空格分隔的搜索词。 例如 ^music .mp3$ sbtrkt !fire
| 代币 | 比赛类型 | 描述 |
|---|---|---|
sbtrkt |
模糊匹配 | 匹配的项目 sbtrkt |
'wild |
精确匹配(引用) | 项目包括 wild |
^music |
前缀精确匹配 | 开头的项目 music |
.mp3$ |
后缀精确匹配 | 以结尾的项目 .mp3 |
!fire |
反向精确匹配 | 不包括的项目 fire |
!^music |
反向前缀精确匹配 | 不以以下开头的项目 music |
!.mp3$ |
反向后缀精确匹配 | 不以结尾的项目 .mp3 |
如果您不喜欢模糊匹配并且不希望“引用”每个单词,请使用 -e 或 --exact 选项启动 fzf。 请注意,当 --exact 设置时, ' -prefix “取消引用”该术语。
单个条形字符术语充当 OR 运算符。 例如,以下查询匹配以 、 或 开头 和 结尾 core 的条目 。 go rb py
^core go$ | rb$ | py$
环境变量
FZF_DEFAULT_COMMAND- 输入为 tty 时使用的默认命令
- 例如
export FZF_DEFAULT_COMMAND='fd --type f' - > ⚠️ 由于要求略有不同,shell 扩展不使用此变量。
>
> (例如 改为CTRL-T运行、 运行 和 运行 )$FZF_CTRL_T_COMMANDvim **<tab>_fzf_compgen_path()cd **<tab>_fzf_compgen_dir()
>
> 可用选项将在本文档的后面部分进行描述。
FZF_DEFAULT_OPTS- 默认选项
- 例如
export FZF_DEFAULT_OPTS="--layout=reverse --inline-info"
选项
有关选项的完整列表,请参见手册页 ( man fzf )。
演示
如果您通过观看视频学习,请查看 @samoshkin 的这个截屏视频以探索 fzf 功能。
例子
- 示例的 Wiki 页面
- 免责声明:此页面上的示例由社区维护,未经过全面测试
- 高级 fzf 示例
fzf-tmux 脚本
fzf-tmux 是一个 bash 脚本,可在 tmux 窗格中打开 fzf。
# usage: fzf-tmux [LAYOUT OPTIONS] [--] [FZF OPTIONS]
# See available options
fzf-tmux --help
# select git branches in horizontal split below (15 lines)
git branch | fzf-tmux -d 15
# select multiple words in vertical split on the left (20% of screen width)
cat /usr/share/dict/words | fzf-tmux -l 20% --multi --reverse
即使你不在 tmux 上,它仍然可以工作,默默地忽略 -[pudlr] 选项,所以你总是可以 fzf-tmux 在你的脚本中使用。
或者,您可以使用 --height HEIGHT[%] 不以全屏模式启动 fzf 的选项。
fzf --height 40%
命令行的键绑定
安装脚本将为 bash、zsh 和 fish 设置以下键绑定。
CTRL-T- 将选定的文件和目录粘贴到命令行- 设置
FZF_CTRL_T_COMMAND覆盖默认命令 - 设置
FZF_CTRL_T_OPTS为将附加选项传递给 fzf
- 设置
CTRL-R- 将所选命令从历史记录粘贴到命令行- 如果您想按时间顺序查看命令,请
CTRL-R再次按下以切换按相关性排序 - 设置
FZF_CTRL_R_OPTS为将附加选项传递给 fzf
- 如果您想按时间顺序查看命令,请
ALT-C- cd 进入选择的目录- 设置
FZF_ALT_C_COMMAND覆盖默认命令 - 设置
FZF_ALT_C_OPTS为将附加选项传递给 fzf
- 设置
如果您在 tmux 会话中,则可以通过设置 FZF_TMUX_OPTS (例如 -d 40% )在 tmux 拆分窗格或 tmux 弹出窗口中启动 fzf。 请参阅 fzf-tmux --help 可用选项。
可以在 wiki 页面 上找到更多提示。
bash 和 zsh 的模糊补全
文件和目录
如果光标前的单词以触发序列结尾,则可以触发文件和目录的模糊补全,默认为 ** .
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 和 telnet 命令,提供了主机名的模糊完成。 这些名称是从 /etc/hosts 和 ~/.ssh/config 中提取的。
ssh **<TAB>
telnet **<TAB>
环境变量/别名
unset **<TAB>
export **<TAB>
unalias **<TAB>
设置
# Use ~~ as the trigger sequence instead of the default **
export FZF_COMPLETION_TRIGGER='~~'
# Options to fzf command
export FZF_COMPLETION_OPTS='--border --info=inline'
# Use fd (https://github.com/sharkdp/fd) instead of the default find
# command 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"
}
# (EXPERIMENTAL) 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 "$@" ;;
esac
}
支持的命令
在 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” 的命令,使用helper 定义 _fzf_complete_COMMAND 函数 。 _fzf_complete
# 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
Vim 插件
请参阅 README-VIM.md 。
高级主题
表现
fzf 很快,而且 越来越快 。 在大多数用例中,性能应该不是问题。 但是,您可能希望了解影响性能的选项。
--ansi告诉 fzf 在输入中提取和解析 ANSI 颜色代码,这会使初始扫描速度变慢。 所以不建议您将其添加到您的$FZF_DEFAULT_OPTS.--nth使 fzf 变慢,因为它必须标记每一行。--with-nth使 fzf 变慢,因为 fzf 必须标记并重新组装每一行。- 如果你绝对需要更好的性能,你可以考虑使用
--algo=v1(默认是v2)让 fzf 使用更快的贪心算法。 但是,此算法不能保证找到匹配的最佳顺序,因此不推荐使用。
执行外部程序
execute 您可以在不离开 fzf ( , 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'
有关详细信息,请参阅手册页的 KEY BINDINGS 部分。
重新加载候选人名单
通过将动作绑定 reload 到键或事件,您可以使 fzf 动态重新加载候选列表。 有关详细信息, 请参阅 #1750 。
1. 按 CTRL-R 更新进程列表
FZF_DEFAULT_COMMAND='ps -ef' \
fzf --bind 'ctrl-r:reload(eval "$FZF_DEFAULT_COMMAND")' \
--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 不执行任何二次过滤。
INITIAL_QUERY=""
RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case "
FZF_DEFAULT_COMMAND="$RG_PREFIX '$INITIAL_QUERY'" \
fzf --bind "change:reload:$RG_PREFIX {q} || true" \
--ansi --disabled --query "$INITIAL_QUERY" \
--height=50% --layout=reverse
如果 ripgrep 没有找到任何匹配项,它将以非零退出状态退出,并且 fzf 将警告您。 为了抑制警告消息,我们 || true 在命令中添加了它,以便它始终以 0 退出。
有关带有预览窗口选项的更完整示例,请参阅 “使用 fzf 作为交互式 Ripgrep 启动器” 。
预览窗口
设置该 --preview 选项后,fzf 会自动以当前行作为参数启动外部进程,并在拆分窗口中显示结果。 您 $SHELL 用于执行带有 $SHELL -c COMMAND . 可以使用鼠标或自定义键绑定来滚动窗口。
# {} is replaced with the single-quoted string of the focused line
fzf --preview 'cat {}'
预览窗口支持 ANSI 颜色,因此您可以使用任何语法高亮文件内容的程序,例如 Bat 或 Highlight :
fzf --preview 'bat --style=numbers --color=always --line-range :500 {}'
您可以使用选项自定义预览窗口的大小、位置和边框,以及使用 --preview-window 选项自定义预览窗口的前景色和背景色 --color 。 例如,
fzf --height 40% --layout reverse --info inline --border \
--preview 'file {}' --preview-window up,1,border-horizontal \
--color 'fg:#bbccdd,fg+:#ddeeff,bg:#334455,preview-bg:#223344,border:#778899'
有关选项的完整列表,请参见手册页 ( man fzf )。
可以在 此处 找到更高级的示例。
由于 fzf 是通用文本过滤器而不是文件查找器, 因此将 --preview 选项添加到您的 $FZF_DEFAULT_OPTS .
# *********************
# ** DO NOT DO THIS! **
# *********************
export FZF_DEFAULT_OPTS='--preview "bat --style=numbers --color=always --line-range :500 {}"'
# bat doesn't work with any input other than the list of files
ps -ef | fzf
seq 100 | fzf
history | fzf
尖端
尊重 .gitignore
您可以使用 fd 、 ripgrep 或 silver searcher 而不是默认的 find 命令来遍历文件系统,同时尊重 .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 fd instead of find
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'
鱼壳
CTRL-T fish 的键绑定与 bash 和 zsh 的键绑定不同,它将使用命令行上的最后一个标记作为递归搜索的根目录。 例如,点击 CTRL-T 以下命令行的末尾
ls /var/
将列出 . 下的所有文件和目录 /var/ 。
使用自定义 FZF_CTRL_T_COMMAND 时,使用未扩展的 $dir 变量来利用此功能。 $dir 默认为 . 最后一个标记不是有效目录时。 例子:
set -g FZF_CTRL_T_COMMAND "command find -L \$dir -type f 2> /dev/null | sed '1d; s#^\./##'"