Skip to content

FZF Mastery: The Interactive Glue๐Ÿ”—

Consult the map

Basic history searching (Ctrl+r) is most people's first and only use of fzf. But fzf is more than a history tool โ€” it's a universal interactive filter, the "glue" that turns static lists into interactive workflows. This is how custom CLI interfaces get built.

fzf takes any list of text, lets you filter it in real-time, and outputs your selection. This simple primitive can be combined with almost any other tool to create powerful, custom workflows.

Installation๐Ÿ”—

Install fzf on Linux
1
2
3
4
5
# Debian/Ubuntu
sudo apt-get update && sudo apt-get install fzf

# RHEL/CentOS/Fedora
sudo dnf install fzf
Install fzf on macOS
brew install fzf
$(brew --prefix)/opt/fzf/install  # (1)!
  1. Sets up the Ctrl+r history and Ctrl+t file-widget key bindings for your shell.
Install fzf on Windows
1
2
3
choco install fzf
# or
scoop install fzf

The Core Concept: One Filter, Many Lists๐Ÿ”—

The same primitive sits in front of almost any list you'd otherwise scroll through by hand:

graph LR
    Files["File names"] --> FZF{{"fzf"}}
    Procs["Process list"] --> FZF
    Branches["Git branches"] --> FZF
    Pods["Pod names"] --> FZF
    FZF --> Open["Open in editor"]
    FZF --> Kill["Kill selected"]
    FZF --> Checkout["Checkout branch"]
    FZF --> Logs["Tail logs"]

    style Files fill:#2d3748,stroke:#cbd5e0,stroke-width:2px,color:#fff
    style Procs fill:#2d3748,stroke:#cbd5e0,stroke-width:2px,color:#fff
    style Branches fill:#2d3748,stroke:#cbd5e0,stroke-width:2px,color:#fff
    style Pods fill:#2d3748,stroke:#cbd5e0,stroke-width:2px,color:#fff
    style FZF fill:#d69e2e,stroke:#cbd5e0,stroke-width:2px,color:#000
    style Open fill:#2f855a,stroke:#cbd5e0,stroke-width:2px,color:#fff
    style Kill fill:#2f855a,stroke:#cbd5e0,stroke-width:2px,color:#fff
    style Checkout fill:#2f855a,stroke:#cbd5e0,stroke-width:2px,color:#fff
    style Logs fill:#2f855a,stroke:#cbd5e0,stroke-width:2px,color:#fff

Every alias and scenario below is the same shape: pipe a list in, get one selection out, hand it to the next command.

Quick Start: The One-Liners๐Ÿ”—

Add these to your aliases for immediate impact:

FZF Multipliers
1
2
3
4
5
6
7
8
# Select a file and open it in your editor
alias fo='fd --type f | fzf | xargs -r ${EDITOR:-vim}'

# Select a process to kill
alias pk='ps -ef | fzf --header-line=1 | awk "{print \$2}" | xargs kill -9'

# Select a git branch to checkout
alias gc='git branch | fzf | xargs git checkout'

Why FZF Matters for Platform Work๐Ÿ”—

SREs spend their time navigating complex namespaces and large numbers of resources. fzf allows you to navigate these without having to memorize names or copy-paste from the terminal.

Common Scenarios๐Ÿ”—

Stop typing pod names manually. Select from a live list:

Interactive Logs
1
2
3
kl() {
  kubectl logs -f $(kubectl get pods -o name | fzf --prompt="Pod > ")
}

Select multiple containers to stop and remove at once:

Bulk Cleanup
1
2
3
4
dc() {
  docker ps -a --format '{{.ID}}    {{.Names}}  {{.Status}}' | 
  fzf --multi --header-line=0 | awk '{print $1}' | xargs docker rm -f
}

Use fzf to explore large JSON files interactively (requires jq):

JSON Browser
# Select a key from a JSON object
cat config.json | jq -r 'keys[]' | fzf | xargs -I {} jq '.{}' config.json

Advanced FZF Features๐Ÿ”—

Three flags turn a basic selector into a real interface:

  • The Preview Window


    Why it matters: See the contents of a file or the details of a resource before you select it, instead of guessing from the filename alone.

    Preview Files While Filtering
    fzf --preview 'bat --color=always {}'
    
  • Multi-Select (-m)


    Why it matters: Select multiple items using Tab, then act on all of them at once. Perfect for bulk operations like deleting a batch of files or stopping several services.

    Select Multiple Files, Then Remove Them
    fzf --multi | xargs -r rm
    
  • Custom Bindings


    Why it matters: Bind keys within fzf itself to perform actions on the highlighted item, without exiting the selector first.

    Open a File in Vim Without Leaving fzf
    fzf --bind 'ctrl-e:execute(vim {})'
    

Practice Problems๐Ÿ”—

Practice Problem 1: Previews

How would you create an fzf command that lists all files in the current directory and shows a preview of the first 10 lines of each file as you move through the list?

Answer
Preview First 10 Lines of Each File
fzf --preview 'head -n 10 {}'
Practice Problem 2: Extraction

When you pipe ps -ef into fzf, the output contains many columns. How do you extract just the PID (the second column) of the selected line?

Answer

Extract the PID Column from a Selection
ps -ef | fzf | awk '{print $2}'
awk is the perfect partner for fzf when you need to extract specific fields from a structured line of text.

Key Takeaways๐Ÿ”—

Feature Flag Purpose
Multi-select -m or --multi Select multiple items with Tab
Preview --preview 'cmd' Run a command on the current item
Prompt --prompt 'text' Change the input prompt
Header --header 'text' Add a static header at the top
Exact Match -e Use exact matching instead of fuzzy

What's Next๐Ÿ”—

If you're following the Debugging With Nothing But a Terminal pathway, the next step is Multiple AI CLIs, One tmux Session โ€” filtering one list interactively is one pane's worth of work; the next step is running several panes at once and moving answers between them.

Further Reading๐Ÿ”—

Official Documentation๐Ÿ”—

  • Skim - A similar fuzzy finder written in Rust.
  • Peco - Another interactive filtering tool.

Deep Dives๐Ÿ”—

  • Pipes and Redirection - The core Unix philosophy โ€” small tools connected by pipes โ€” that makes fzf so powerful as connective tissue.