Basic Usage
fzf opens a full-screen TUI where you type a query to filter the input list and press Enter to output your selection. This lesson covers everything you need to use fzf from day one.
Invoking fzf
# Read from stdin (most common)
command | fzf
# Read from a file
fzf < filelist.txt
# No stdin — fzf runs find . by default
fzf # equivalent to: find . | fzf
The fzf TUI
┌─────────────────────────────────────────────────┐
│ > nginx ← your query│
│ 15 / 1024 ← match count│
│ ▶ /etc/nginx/nginx.conf │
│ /etc/nginx/sites-available/default │
│ /var/log/nginx/error.log │
│ /var/log/nginx/access.log │
└─────────────────────────────────────────────────┘
| Element | Meaning |
|---|---|
> prompt | Your query input |
15 / 1024 | 15 matches out of 1024 total items |
▶ pointer | Currently highlighted item |
Default Key Bindings
Navigation
| Key | Action |
|---|---|
↑ / Ctrl+k / Ctrl+p | Move up |
↓ / Ctrl+j / Ctrl+n | Move down |
Page Up | Scroll up one page |
Page Down | Scroll down one page |
Home | Go to first item |
End | Go to last item |
Ctrl+u | Clear query |
Ctrl+a | Select all (with -m) |
Ctrl+d | Deselect all (with -m) |
Confirmation
| Key | Action |
|---|---|
Enter | Accept selection |
Esc / Ctrl+c | Cancel (exit 130) |
Ctrl+q | Cancel |
Text Editing
| Key | Action |
|---|---|
Ctrl+w | Delete previous word |
Ctrl+u | Clear the query |
← → | Move cursor in query |
Ctrl+a | Move to start of query |
Ctrl+e | Move to end of query |
Essential Flags
--multi / -m — Select Multiple Items
ls | fzf -m
# Tab to mark items, Shift+Tab to unmark, Enter to output all marked
| Key | Action |
|---|---|
Tab | Toggle selection |
Shift+Tab | Toggle selection (backward) |
Ctrl+a | Select all |
Ctrl+d | Deselect all |
Multi-select output: one selected item per line.
--query / -q — Pre-fill the Query
ls /etc | fzf --query "nginx"
# Opens fzf with "nginx" already typed
--select-1 / -1 — Auto-select If Only One Match
ls | fzf --query "nginx.conf" --select-1
# If exactly one result matches, skip TUI and output it directly
--exit-0 / -0 — Exit Immediately If No Match
ls | fzf --query "doesnotexist" --exit-0
# Exits with code 1 if no matches — useful in scripts
--filter / -f — Non-interactive (Batch) Mode
ls | fzf --filter "conf"
# Outputs all matches without TUI (like grep but fuzzy)
# Useful for scripting without user interaction
--height — Use Partial Screen Height
ls | fzf --height 40%
# fzf uses 40% of screen height instead of full screen
--reverse — Input at Top
ls | fzf --reverse
# Query prompt and results start from top of screen
--prompt — Custom Prompt Text
ls | fzf --prompt " Open file: "
--header — Informational Header
ls | fzf --header "Select a file to edit (Enter to open)"
Reading the Exit Code
fzf returns different exit codes:
| Exit code | Meaning |
|---|---|
0 | Item selected |
1 | No match (with --exit-0) or no selection |
130 | Interrupted with Ctrl+c or Esc |
# In scripts:
selected=$(ls | fzf)
if [ $? -eq 0 ]; then
echo "You selected: $selected"
elif [ $? -eq 130 ]; then
echo "Cancelled"
fi
The --print0 Flag — Handle Filenames with Spaces
# Safe for filenames containing spaces or special characters
find . -name "*.txt" -print0 | fzf --read0 --print0 | xargs -0 cat
Practical First Commands
# Pick a file to edit
nvim "$(find . -type f | fzf)"
# Pick multiple files to delete (with confirmation)
find . -name "*.tmp" | fzf -m | xargs -I{} rm -v {}
# Pick a running process to kill
kill $(ps aux | fzf | awk '{print $2}')
# Pick a line from a log file to examine
grep -n "" /var/log/syslog | fzf | cut -d: -f1
# Select from history and run
eval $(history | awk '{$1=""; print $0}' | fzf)