1. What it is#
fzf (fuzzy finder) is a general-purpose command-line fuzzy search tool. Its operating model is simple: read a list from stdin → filter interactively → write the selected result to stdout.
ls | fzf # 从文件列表中选一个Compared with Ctrl+R (history search), fzf is general-purpose: it can search file lists, process lists, git branches, or any list of text.
2. Basic usage#
# 模糊搜文件然后用 vim 打开
IFS= read -r -d '' selected < <(find . -type f -print0 | fzf --read0 --print0) && nvim -- "$selected"
# 搜进程并 kill
ps -eo pid=,comm=,args= | fzf | awk '{print $1}' | xargs -r -p kill
# 从命令历史中选一条,先显示核对,再手动执行
history | fzf | awk '{$1=""; print $0}'3. Common combinations#
# 快速 cd(配合 zoxide)
selected=$(zoxide query --list | fzf) && [ -n "$selected" ] && cd -- "$selected"
# 搜 git branch 并切换
git for-each-ref --format='%(refname:short)' refs/heads | fzf | xargs -r git switch
# 搜 commit 并 cherry-pick
git log --oneline | fzf | awk '{print $1}' | xargs -r -p git cherry-pick
# 搜文件内容并打开
rg -l -0 "" | fzf --read0 --print0 | xargs -0 -r -o nvim --4. Keyboard shortcuts#
| Key | Action |
|---|---|
Ctrl+n / Ctrl+p |
Move up/down |
Ctrl+j / Ctrl+k |
Move up/down (vi style) |
Enter |
Confirm selection |
Esc / Ctrl+c |
Cancel |
Ctrl+a / Ctrl+e |
Jump to the beginning / end of the line |
Tab |
Mark multiple selections |
5. Common options#
fzf --multi # Tab 多选
fzf --preview 'cat -- {}' # 右侧预览文件内容
fzf --preview 'bat --color=always -- {}' # 语法高亮预览
fzf --preview 'ls -la -- {}' # 预览目录内容
fzf --height 40% # 占终端 40% 高度,不占全屏
fzf --layout=reverse # 搜索框在顶部6. Advanced bindings (shell integration)#
After installing fzf, enable shell integration to replace the default Ctrl+R and Ctrl+T:
# bash/zsh: 在 .bashrc 或 .zshrc 中添加
eval "$(fzf --bash)" # 或 --zsh
# fish: fzf 自带 fish 集成,或在 config.fish 中
fzf --fish | sourceOnce enabled, you get:
Ctrl+R— fuzzy-search command history (replaces the native binding)Ctrl+T— fuzzy-search files in the current directory and paste the pathAlt+C— fuzzy-search directories and cd to one
Everyday use: quick reference#
| I want to... | Command |
|---|---|
| Quickly open a file | Use the NUL-delimited read example above |
| Switch to a git branch | git for-each-ref --format='%(refname:short)' refs/heads | fzf | xargs -r git switch |
| Kill a process | ps -eo pid=,comm=,args= | fzf | awk '{print $1}' | xargs -r -p kill |
| Search command history | Ctrl+R (after enabling fzf shell integration) |
| Select a file and preview its contents | fzf --preview 'bat {}' |
The assignment, read -d, and process-substitution examples above use Bash. -r, -o, and -p are the GNU xargs options used here. Terminating processes and running cherry-pick change state, so first inspect the selected PID or commit and the working tree. fzf is only a selector; you still need to check the upstream list and downstream operation. Ordinary newline-delimited lists are unsuitable for filenames containing newlines. fzf --bash/--zsh/--fish requires a version that supports that interface; for older versions, enable integration using the scripts supplied by the installed package.
References & further reading
Adapted from technical notes. Examples use generic names.