Skip to content

fzf (Fuzzy Finder) Cheatsheet

Installation

Platform Command
Ubuntu/Debian sudo apt update && sudo apt install fzf
Fedora/RHEL sudo dnf install fzf
Arch Linux sudo pacman -S fzf
macOS (Homebrew) brew install fzf && $(brew --prefix)/opt/fzf/install
Windows (Chocolatey) choco install fzf
Windows (Scoop) scoop install fzf
Windows (winget) winget install fzf
From Source git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf && ~/.fzf/install

Post-Installation Shell Integration:

# Bash
echo '[ -f ~/.fzf.bash ] && source ~/.fzf.bash' >> ~/.bashrc

# Zsh
echo '[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh' >> ~/.zshrc

Basic Commands

Command Description
fzf Launch interactive fuzzy finder on stdin or files
vim $(fzf) Find and open file in vim
ls \| fzf Fuzzy search through ls output
fzf --multi Enable multi-selection mode (use Tab to select)
fzf --preview 'cat {}' Show file preview while browsing
fzf --reverse Display results from top to bottom
fzf --height 40% Set finder height to 40% of screen
fzf --border Add border around finder interface
fzf --prompt "Select: " Customize the input prompt
fzf --exact Use exact matching instead of fuzzy
fzf +i Enable case-sensitive search
fzf --inline-info Display info inline with prompt
find . -name "*.py" \| fzf Find and filter specific file types
ps aux \| fzf Interactively search running processes
history \| fzf Search through command history

Default Key Bindings

Key Binding Action
Ctrl+T Paste selected files/directories into command line
Ctrl+R Search command history and paste selected command
Alt+C Fuzzy find directory and cd into it
**<Tab> Trigger fuzzy completion (e.g., vim **<Tab>)
Ctrl+J / Ctrl+N Move cursor down
Ctrl+K / Ctrl+P Move cursor up
Enter Select item and exit
Tab Select/deselect item in multi-select mode
Shift+Tab Deselect item in multi-select mode
Ctrl+C / Esc Cancel and exit

Advanced Usage

Command Description
fzf --preview 'bat --color=always {}' Preview with syntax highlighting using bat
fzf --preview-window=right:50% Position preview window on right at 50% width
fzf --preview-window=hidden Start with preview hidden (toggle with Ctrl+/)
fzf --bind 'ctrl-e:execute(vim {})' Execute vim on selected item with Ctrl+E
fzf --bind 'ctrl-y:execute-silent(echo {} \| pbcopy)' Copy selection to clipboard silently
fzf --delimiter=' ' --nth=2.. Search only from 2nd field onwards
fzf --header="Select file to edit" Add header text to finder
fzf --color=dark Use dark color scheme
fzf --query="initial" Pre-populate search query
fzf --select-1 --exit-0 Auto-select if one match, exit if none
fzf --expect=ctrl-d,ctrl-e Return different exit codes for different keys
fzf --print-query Print query string even if no match
fzf --cycle Enable result cycling (wrap around)
fzf --no-mouse Disable mouse support
fzf --algo=v2 Use faster matching algorithm for large datasets
fzf --tac Reverse input order
fzf --no-sort Disable sorting, keep input order
fzf --border=rounded Use rounded border style
fzf --sync Use synchronous filtering (no async)
fzf --scroll-off=5 Keep selected item 5 lines from edge

Configuration

Environment Variables

Primary Configuration File: ~/.bashrc or ~/.zshrc

# Default command for finding files (using fd)
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'

# Default options applied to all fzf invocations
export FZF_DEFAULT_OPTS='
  --height 40%
  --layout=reverse
  --border
  --inline-info
  --preview "bat --style=numbers --color=always --line-range :500 {}"
  --preview-window=right:50%:hidden
  --bind "ctrl-/:toggle-preview"
  --bind "ctrl-y:execute-silent(echo {} | pbcopy)"
'

# Ctrl+T configuration (file finder)
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_CTRL_T_OPTS="
  --preview 'bat --color=always --line-range :50 {}'
  --bind 'ctrl-/:change-preview-window(down|hidden|)'
"

# Alt+C configuration (directory finder)
export FZF_ALT_C_COMMAND='fd --type d --hidden --follow --exclude .git'
export FZF_ALT_C_OPTS="
  --preview 'tree -C {} | head -50'
"

# Ctrl+R configuration (history search)
export FZF_CTRL_R_OPTS="
  --preview 'echo {}'
  --preview-window up:3:hidden:wrap
  --bind 'ctrl-/:toggle-preview'
  --bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort'
  --color header:italic
  --header 'Press CTRL-Y to copy command into clipboard'
"

Color Scheme Configuration

# Monokai theme
export FZF_DEFAULT_OPTS='
  --color=bg+:#293739,bg:#1B1D1E,border:#808080
  --color=spinner:#E6DB74,hl:#7E8E91,fg:#F8F8F2
  --color=header:#7E8E91,info:#A6E22E,pointer:#A6E22E
  --color=marker:#F92672,fg+:#F8F8F2,prompt:#F92672,hl+:#F92672
'

# Dracula theme
export FZF_DEFAULT_OPTS='
  --color=fg:#f8f8f2,bg:#282a36,hl:#bd93f9
  --color=fg+:#f8f8f2,bg+:#44475a,hl+:#bd93f9
  --color=info:#ffb86c,prompt:#50fa7b,pointer:#ff79c6
  --color=marker:#ff79c6,spinner:#ffb86c,header:#6272a4
'

# Nord theme
export FZF_DEFAULT_OPTS='
  --color=fg:#e5e9f0,bg:#3b4252,hl:#81a1c1
  --color=fg+:#e5e9f0,bg+:#434c5e,hl+:#81a1c1
  --color=info:#eacb8a,prompt:#bf6069,pointer:#b48dac
  --color=marker:#a3be8b,spinner:#b48dac,header:#a3be8b
'

Common Use Cases

Use Case: Git Branch Checkout

# Interactive git branch selection
git checkout $(git branch -a | fzf | sed 's/^[ *]*//' | sed 's/remotes\/origin\///')

# Or create an alias
alias gcb='git checkout $(git branch | fzf | sed "s/^[ *]*//")'

Use Case: Kill Process

# Find and kill process interactively
kill -9 $(ps aux | fzf | awk '{print $2}')

# Or create a function
fkill() {
  local pid
  pid=$(ps aux | sed 1d | fzf -m | awk '{print $2}')
  if [ "x$pid" != "x" ]; then
    echo $pid | xargs kill -${1:-9}
  fi
}

Use Case: SSH Host Selection

# Select from SSH config hosts
ssh $(grep "^Host" ~/.ssh/config | grep -v "[?*]" | cut -d " " -f2- | fzf)

# Or create an alias
alias fssh='ssh $(grep "^Host" ~/.ssh/config | grep -v "[?*]" | cut -d " " -f2- | fzf)'

Use Case: Directory Navigation with History

# Create a function to track and jump to directories
fcd() {
  local dir
  dir=$(find ${1:-.} -path '*/\.*' -prune -o -type d -print 2> /dev/null | fzf +m) && cd "$dir"
}

# Jump to frequently used directories (requires z or autojump)
fz() {
  local dir
  dir=$(z -l 2>&1 | fzf --height 40% --nth 2.. --reverse --inline-info +s --tac --query "${*}" | sed 's/^[0-9,.]* *//')
  cd "$dir"
}

Use Case: Docker Container Management

# Select and attach to running container
docker exec -it $(docker ps | fzf | awk '{print $1}') /bin/bash

# Select and stop containers
docker stop $(docker ps -a | fzf -m | awk '{print $1}')

# Select and remove images
docker rmi $(docker images | fzf -m | awk '{print $3}')

Use Case: Environment Variable Viewer

# Browse and copy environment variables
env | fzf --preview 'echo {}' --preview-window=up:3:wrap \
  --bind 'enter:execute(echo {} | cut -d= -f2 | pbcopy)+abort'

Use Case: Log File Analysis

# Search through log files with preview
find /var/log -type f 2>/dev/null | fzf \
  --preview 'tail -100 {}' \
  --bind 'enter:execute(less {})'

# Search log content
grep -r "ERROR" /var/log 2>/dev/null | fzf \
  --delimiter=: \
  --preview 'bat --color=always {1} --highlight-line {2}' \
  --preview-window +{2}-/2

Best Practices

  • Use with fd or ripgrep: Replace find with fd for faster file searching: export FZF_DEFAULT_COMMAND='fd --type f'

  • Enable preview by default: Add preview windows to see file contents before selection, improving accuracy and reducing mistakes

  • Create shell aliases: Build custom aliases for frequent workflows (git operations, SSH connections, process management) to maximize productivity

  • Combine with other tools: Integrate fzf with bat for syntax highlighting, tree for directory previews, and delta for git diffs

  • Use multi-select wisely: Enable --multi mode when you need to operate on multiple items (deleting files, checking out multiple git files)

  • Leverage key bindings: Customize --bind options to create shortcuts for common actions (open in editor, copy to clipboard, execute commands)

  • Optimize for large datasets: Use --algo=v2 and consider --sync mode for very large file lists to improve performance

  • Set appropriate heights: Use --height 40% or similar to avoid full-screen takeover, maintaining context of your current work

  • Configure color schemes: Match fzf colors to your terminal theme for better visual integration and reduced eye strain

  • Use field delimiters: When parsing structured output (like ps or docker), use --delimiter and --nth to search specific columns

Troubleshooting

Issue Solution
Key bindings not working Run the install script: ~/.fzf/install or source the shell integration file in your RC file
Slow performance with large file lists Use fd or ripgrep instead of find: export FZF_DEFAULT_COMMAND='fd --type f' and consider --algo=v2
Preview not showing file contents Ensure preview command is correct and file is readable. Try --preview 'cat {}' or install bat for better previews
Colors not displaying correctly Check terminal supports 256 colors. Use --color=16 for basic color support or adjust color scheme
Command not found after installation Add fzf to PATH or restart shell. For Homebrew: ensure /usr/local/bin or /opt/homebrew/bin is in PATH
Unicode characters not rendering Ensure terminal and locale support UTF-8: export LC_ALL=en_US.UTF-8 and use a Unicode-capable font
fzf consuming too much memory Reduce input size or use --sync mode. Consider filtering input before piping to fzf
Preview window not updating Use --preview-window=follow for auto-scrolling or toggle preview with Ctrl+/ to refresh
Cannot select items with mouse Mouse support may be disabled. Remove --no-mouse option or click outside fzf and retry
Completion not working with **<Tab> Ensure shell integration is loaded. Check ~/.fzf.bash or ~/.fzf.zsh is sourced in your RC file

Search Syntax

Syntax Description Example
term Fuzzy match fzf with input "abc" matches "a_b_c.txt"
'term Exact match (single quote prefix) 'abc matches only "abc" exactly
^term Prefix exact match ^abc matches "abc..." but not "zabc"
term$ Suffix exact match abc$ matches "...abc" but not "abcz"
!term Inverse match (exclude) !test excludes lines with "test"
term1 term2 AND match (both required) foo bar matches lines with both terms
term1 \| term2 OR match (either required) foo \| bar matches lines with either term

Useful Shell Functions

# Open file in editor with preview
fe() {
  local files
  files=$(fzf --query="$1" --multi --select-1 --exit-0 \
    --preview 'bat --color=always --line-range :500 {}')
  [[ -n "$files" ]] && ${EDITOR:-vim} "${files[@]}"
}

# Change to directory with preview
fcd() {
  local dir
  dir=$(fd --type d --hidden --follow --exclude .git | fzf \
    --preview 'tree -C {} | head -100') && cd "$dir"
}

# Git commit browser
fgc() {
  git log --oneline --color=always | fzf --ansi \
    --preview 'git show --color=always {1}' \
    --bind 'enter:execute(git show {1} | less -R)'
}

# Browse and install packages (Debian/Ubuntu)
fap() {
  apt-cache search . | fzf --multi --preview 'apt-cache show {1}' | \
    awk '{print $1}' | xargs -ro sudo apt install
}