fzf - Street-Level Ops¶
Real-world workflows for interactive selection and filtering in DevOps tasks.
Quick Interactive File Finder¶
# Pick a file from the project and open it
vim $(fd -t f | fzf)
# Pick a file with preview (requires bat or cat)
fd -t f | fzf --preview 'head -40 {}'
# Pick a file with syntax-highlighted preview
fd -t f | fzf --preview 'bat --color=always --line-range :40 {}'
Gotcha: If
fzfshows no results, the input pipe is empty.fdexcludes.git/and respects.gitignoreby default — usefd -H(hidden) orfd -I(no-ignore) if you need those files. Plainfindworks too:find . -type f | fzf.
Kubernetes Operations¶
# Switch namespace interactively
kubectl config set-context --current --namespace \
$(kubectl get ns -o name | sed 's|namespace/||' | fzf)
# Tail logs from a selected pod
kubectl get pods -o name | fzf | xargs -I{} kubectl logs -f {}
# Exec into a selected pod
kubectl get pods -o name | fzf --preview 'kubectl describe {}' | \
xargs -I{} kubectl exec -it {} -- sh
# Delete a selected pod (with confirmation preview)
kubectl get pods | fzf --header-lines=1 | awk '{print $1}' | \
xargs -p kubectl delete pod
# Describe a selected deployment
kubectl get deployments -o name | fzf --preview 'kubectl get {} -o yaml' | \
xargs kubectl describe
# Select multiple pods to restart
kubectl get pods -o name | fzf -m | xargs kubectl delete
Remember:
Tabselects/deselects in multi-mode (-m).Shift+Tabdeselects.Ctrl+Aselects all (if you add--bind 'ctrl-a:select-all'). These keybindings turn fzf from "pick one thing" into "batch operations on chosen items."Default trap:
fzfwithout input falls back tofind .which can be extremely slow in large repos or directories withnode_modules. Always setFZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'in your shell profile —fdrespects.gitignoreand is 10-50x faster thanfind.
Git Operations¶
# Checkout a branch interactively
git branch -a | sed 's/^\*//' | fzf | xargs git checkout
# Browse git log and preview commits
git log --oneline --all | fzf --preview 'git show --stat {1}'
# Stage files interactively (multi-select with Tab)
git diff --name-only | fzf -m | xargs git add
# View a specific commit's diff
git log --oneline | fzf --preview 'git diff {1}^..{1}' | awk '{print $1}'
# Cherry-pick from another branch
git log --oneline other-branch | fzf | awk '{print $1}' | xargs git cherry-pick
Docker Operations¶
# Exec into a running container
docker exec -it $(docker ps --format '{{.Names}}' | fzf) bash
# View logs from a selected container
docker ps --format '{{.Names}}' | fzf | xargs docker logs -f
# Remove stopped containers interactively
docker ps -a --format '{{.Names}} ({{.Status}})' | fzf -m | \
awk '{print $1}' | xargs docker rm
# Select an image to inspect
docker images --format '{{.Repository}}:{{.Tag}}' | fzf | xargs docker inspect
One-liner: Interactive
git stashbrowser:git stash list | fzf --preview 'git stash show -p {1}' | awk -F: '{print $1}' | xargs git stash apply— preview each stash diff, select one, and apply it.
Log and Process Investigation¶
# Search environment variables
env | fzf
# Filter and kill a process (use -9 only as last resort)
kill $(ps aux | fzf --header-lines=1 | awk '{print $2}')
# Select from grep results and open in editor
rg -n "ERROR" /var/log/app/ | fzf --delimiter=: --preview 'bat --color=always {1} --highlight-line {2}'
# Browse systemd units
systemctl list-units --type=service | fzf --header-lines=1 | awk '{print $1}' | \
xargs systemctl status
SSH Host Selection¶
# Pick an SSH host from config
grep '^Host ' ~/.ssh/config | awk '{print $2}' | fzf | xargs ssh
# Pick a host from /etc/hosts or an inventory file
cat inventory.txt | fzf | xargs ssh
# Pick a host and run a command
HOST=$(cat inventory.txt | fzf)
ssh "${HOST}" 'uptime && df -h / && free -m'
Combining fzf with fd and rg¶
# fd + fzf: find and select files by type
fd -e yaml | fzf -m --preview 'bat --color=always {}'
# rg + fzf: search, select, and open result
rg --color=always --line-number "TODO" | \
fzf --ansi --delimiter=: \
--preview 'bat --color=always {1} --highlight-line {2} --line-range {2}:'
# fd + fzf + editor: find, preview, edit
EDITOR=${EDITOR:-vim}
${EDITOR} $(fd -t f | fzf --preview 'bat --color=always {}')
Multi-Select Workflows¶
# Select multiple files to delete (Tab to select, Enter to confirm)
fd -t f -e bak -e tmp | fzf -m | xargs rm -v
# Select multiple Kubernetes resources to describe
kubectl get all -o name | fzf -m | xargs -I{} kubectl describe {}
# Select multiple git branches to delete
git branch | fzf -m | xargs git branch -d
Shell Setup for Maximum Productivity¶
# Add to ~/.bashrc or ~/.zshrc
eval "$(fzf --bash)" # bash (enables Ctrl-R, Ctrl-T, Alt-C)
# eval "$(fzf --zsh)" # zsh
# Use fd instead of find (much faster)
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
export FZF_DEFAULT_OPTS='--height 40% --layout=reverse --border --info=inline'
# Pro tip: add --bind 'ctrl-/:toggle-preview' to toggle previews with Ctrl-/
export FZF_CTRL_T_COMMAND="${FZF_DEFAULT_COMMAND}"
export FZF_ALT_C_COMMAND='fd --type d --hidden --follow --exclude .git'
# Ctrl-R: fuzzy search command history (built-in after eval)
# Ctrl-T: fuzzy file finder, inserts path at cursor
# Alt-C: fuzzy cd into a directory
Under the hood:
eval "$(fzf --bash)"installs three shell functions that overrideCtrl-R,Ctrl-T, andAlt-C. TheFZF_*_COMMANDvariables control what each binding searches. If you usefdas the default command,Ctrl-Tbecomes blazingly fast even in repos with millions of files.One-liner: Fastest way to find and edit a file containing a pattern:
vim $(rg -l "TODO" | fzf --preview 'rg --color=always "TODO" {}')— search, preview matches, then open.
# Custom keybinding: Ctrl-G to select a git branch
bind '"\C-g": "$(git branch -a | sed s/^..// | fzf)\e\C-e"'
Gotcha: When running fzf inside tmux, use the
--tmuxflag (fzf 0.48+) to render in a tmux popup instead of taking over the terminal. The flag is silently ignored outside tmux, making it safe to hardcode in shell aliases:alias fzfp='fzf --tmux center,80%'.
Preview Window Customization¶
# Right-side preview, 60% width
fd -t f | fzf --preview 'bat --color=always {}' --preview-window=right:60%:wrap
# Hidden preview, toggle with ?
fd -t f | fzf --preview 'bat --color=always {}' --preview-window=hidden --bind '?:toggle-preview'
# Top preview for wide terminals
fd -t f | fzf --preview 'head -20 {}' --preview-window=up:40%