OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 043

Fuzzy finding with fzf

Turn lists of files, processes, branches, and history entries into interactive selection inputs.

English translation · Code and commands follow the Chinese original.

IN THESE READING PATHSLinux command-line fundamentals and composition ↗
About 3 min readStart reading

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 | source

Once 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 path
  • Alt+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

  1. Official fzf documentation ↗
  2. GNU xargs options ↗

Adapted from technical notes. Examples use generic names.

Continue along a reading path

Linux command-line fundamentals and composition

  1. 01File and directory operations
  2. 02Process and job management
  3. 03Text processing and system queries
  4. 04Shell fundamentals
  5. 05Fuzzy finding with fzf
  6. 06Passing arguments with xargs
CONTINUE READING / NEXT ARTICLEPassing arguments with xargs

Convert standard input into command arguments while handling delimiters, placeholders, parallelism, and empty input.