fzf — Interactive Command-Line Fuzzy Finder
Practical guide to fzf — fuzzy-search and select interactively from files, history, processes and git branches, right in your terminal.
fzf is an interactive fuzzy finder for the command line: you type a few characters and fzf filters any list in real time – files, command history, processes, git branches and anything you pipe into it. That turns tedious typing into a handful of keystrokes with a live preview and multi-select. Keep in mind that fzf is third-party software and not part of the base system – you install it separately (via your package manager or the git repository) and then set up the shell integration so that Ctrl+T, Ctrl+R, Alt+C and the ** trigger work. This guide walks you through the invocations and key bindings you actually use day to day, from a simple search to git and process workflows.
Basic Usage
fzf — Launch fuzzy finder on all files in the current directory (recursive).
fzf<command> | fzf — Pipe any list into fzf for interactive selection.
ls -la | fzffzf --query '<string>' — Start with an initial search query.
fzf --query 'config'fzf --filter '<string>' — Non-interactive filter mode (for scripting).
find . -name '*.py' | fzf --filter 'test'fzf --multi — Enable multi-select (Tab to select, Enter to confirm).
fzf --multifzf --select-1 — Auto-select if there is only one match.
fzf --select-1 --query 'unique-name'fzf --exit-0 — Exit immediately if there are no matches.
fzf --exit-0 --query 'nonexistent'Search Syntax
abc — Fuzzy match: items containing a, b, c in that order.
Type 'cfg' to match 'config', 'configuration''<exact> — Exact match (prefix with single quote).
'config matches only lines containing 'config' literally^<prefix> — Prefix match: must start with the string.
^src/ matches lines starting with 'src/'<suffix>$ — Suffix match: must end with the string.
.json$ matches lines ending with '.json'!<term> — Inverse match: exclude lines matching the term.
!test excludes lines containing 'test'<term1> | <term2> — OR operator: match either term.
.js$ | .ts$ matches JavaScript or TypeScript files<term1> <term2> — AND operator: match both terms (space-separated).
src config matches lines containing both 'src' and 'config'Preview & Display
fzf --preview '<command> {}' — Show a preview of the selected item.
fzf --preview 'cat {}'fzf --preview 'bat --color=always {}' — Preview with syntax highlighting (requires bat).
fzf --preview 'bat --color=always --line-range=:100 {}'fzf --preview-window <position> — Set preview position (up, down, left, right, hidden).
fzf --preview 'cat {}' --preview-window right:60%fzf --height <percent> — Limit fzf to a portion of the screen (no fullscreen).
fzf --height 40%fzf --layout reverse — Show results top-down instead of bottom-up.
fzf --layout reverse --height 40%fzf --border — Draw a border around the fzf window.
fzf --border rounded --height 40%Shell Integration (Ctrl Shortcuts)
Ctrl+T — Fuzzy find files and paste the selection to the command line.
vim [Ctrl+T] → select file → EnterCtrl+R — Fuzzy search shell command history.
[Ctrl+R] → type partial command → Enter to executeAlt+C — Fuzzy find directories and cd into the selection.
[Alt+C] → select directory → Enter<command> **<Tab> — Trigger fuzzy completion (files, dirs, hosts, etc.).
vim **[Tab] → fuzzy select filecd **<Tab> — Fuzzy directory completion.
cd **[Tab] → select directoryssh **<Tab> — Fuzzy hostname completion from known_hosts.
ssh **[Tab] → select hostGit Integration
git branch | fzf | xargs git checkout — Interactively select and checkout a branch.
git branch | fzf | xargs git checkoutgit log --oneline | fzf --preview 'git show {1}' — Browse commits with preview.
git log --oneline | fzf --preview 'git show {1}'git diff --name-only | fzf --preview 'git diff {}' — Browse changed files with diff preview.
git diff --name-only | fzf --multi --preview 'git diff {}'git stash list | fzf | cut -d: -f1 | xargs git stash pop — Interactively select and pop a stash.
git stash list | fzf | cut -d: -f1 | xargs git stash popCommon Patterns
vim $(fzf) — Find and open a file in vim.
vim $(fzf --preview 'cat {}')kill -9 $(ps aux | fzf | awk '{print $2}') — Interactively select and kill a process.
kill -9 $(ps aux | fzf | awk '{print $2}')docker stop $(docker ps | fzf | awk '{print $1}') — Interactively select and stop a Docker container.
docker stop $(docker ps | fzf | awk '{print $1}')printenv | fzf — Browse and search environment variables.
printenv | fzfcat <file> | fzf --multi | pbcopy — Select lines from a file and copy to clipboard.
cat urls.txt | fzf --multi | pbcopyfind . -name '*.json' | fzf --preview 'cat {}' | xargs code — Find, preview, and open a JSON file in VS Code.
find . -name '*.json' | fzf --preview 'cat {}' | xargs codeEnvironment Variables
FZF_DEFAULT_COMMAND='<cmd>' — Set the default command for file listing.
export FZF_DEFAULT_COMMAND='fd --type f --hidden --exclude .git'FZF_DEFAULT_OPTS='<opts>' — Set default fzf options.
export FZF_DEFAULT_OPTS='--height 40% --layout reverse --border'FZF_CTRL_T_COMMAND='<cmd>' — Customize the file search for Ctrl+T.
export FZF_CTRL_T_COMMAND='fd --type f --hidden'FZF_ALT_C_COMMAND='<cmd>' — Customize the directory search for Alt+C.
export FZF_ALT_C_COMMAND='fd --type d --hidden' Conclusion
fzf makes searching and selecting in the terminal radically faster: you type fuzzily, see matches instantly, and pipe the selection into any other tool – from vim $(fzf) to interactive branch switching in git. Because fzf is third-party software, you have to install it once and enable the shell integration; only then do the shortcuts Ctrl+T, Ctrl+R, Alt+C and the ** completion trigger become available, and some examples assume further helpers such as fd, bat or pbcopy. Be careful with combinations like … | fzf | xargs git checkout or kill -9 $(…): fzf only provides the selection, the effect comes from the downstream command – so check what you actually run after selecting.
Further Reading
- fzf on GitHub – the official project with installation, docs and examples
- fzf wiki: examples – a large collection of practical usage examples