| name | modern-cli-tools |
| description | Use fd, rg, fzf, and bat as modern replacements for find, grep, interactive selection, and cat. Prefer these tools for faster, friendlier, and more ergonomic file searching, content searching, fuzzy filtering, and file viewing. |
Modern CLI Tools
Use fd, rg, fzf, and bat instead of their legacy counterparts. Each is faster, has sensible defaults (respects .gitignore, colorizes output, handles Unicode), and has a more consistent interface.
| Modern | Replaces | Purpose |
|---|
fd | find | Find files and directories |
rg | grep -r | Search file contents |
fzf | manual selection | Fuzzy-filter any list interactively |
bat | cat | View file contents with syntax highlighting |
fd — Find Files
Install: brew install fd / apt install fd-find (binary may be fdfind)
Basic Usage
fd PATTERN
fd PATTERN PATH
fd -e py
fd -t f
fd -H
fd -I
fd -0
Common Replacements
fd -e md
fd -e log --changed-before 7d
fd -e py -x grep -l "import os"
fd -t d __pycache__
fd -e json --max-depth 2
Execute Commands on Results
fd -e py -x wc -l
fd -e log -X rm
fd -e html -x sed -i 's/foo/bar/g'
rg — Ripgrep (Search File Contents)
Install: brew install ripgrep / apt install ripgrep
Basic Usage
rg PATTERN
rg PATTERN PATH
rg -i PATTERN
rg -l PATTERN
rg -c PATTERN
rg -n PATTERN
rg -v PATTERN
rg -w PATTERN
rg -F PATTERN
rg -U PATTERN
Filtering by File Type
rg PATTERN -t py
rg PATTERN -t js -t ts
rg PATTERN -T json
rg --type-list
Common Replacements
rg "TODO" -t py
rg "def main" src/
rg -l "import React"
rg "password"
rg "^class " -t ruby
Useful Flags
rg PATTERN -A 3
rg PATTERN -B 3
rg PATTERN -C 3
rg PATTERN --hidden
rg PATTERN -g "*.md"
rg PATTERN -g "!vendor/"
rg PATTERN --no-ignore
rg PATTERN -j 4
rg PATTERN -o
rg PATTERN --stats
fzf — Fuzzy Finder
Install: brew install fzf / apt install fzf
fzf reads from stdin and lets the user interactively fuzzy-filter the input. It prints the selected item(s) to stdout, making it composable with any other command.
Basic Interactive Use
fzf
fzf -m
fzf -q "initial query"
fzf --height 40%
fzf --reverse
fzf --border
Find and Open Files
$EDITOR $(fzf)
FZF_DEFAULT_COMMAND='fd -t f' fzf
fzf --preview 'bat --color=always {}'
Search and Jump
git log --oneline | fzf --preview 'git show {1}'
git branch | fzf | xargs git checkout
ps aux | fzf -m | awk '{print $2}' | xargs kill
cd $(fd -t d | fzf)
Pipe Integration
rg --line-number "TODO" | fzf
history | fzf | sh
git status -s | fzf -m | awk '{print $2}' | xargs git add
Shell Integration
After $(brew prefix)/opt/fzf/install or fzf --bash:
Ctrl-R — fuzzy search shell history
Ctrl-T — fuzzy-insert file path at cursor
Alt-C — fuzzy cd into subdirectory
bat — Better cat
Install: brew install bat / apt install bat (binary may be batcat)
Basic Usage
bat FILE
bat FILE1 FILE2
bat -n FILE
bat -A FILE
bat --plain FILE
bat --paging=never FILE
bat -l json FILE
bat --list-languages
Common Replacements
bat file.py
bat -n file.py
bat *.md
bat --plain package.json | jq
Use as a Pager or Previewer
git diff | bat -l diff
fzf --preview 'bat --color=always --style=numbers {}'
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
Useful Flags
bat --style=plain
bat --style=numbers,grid
bat --color=always
bat --wrap=never
bat -r 10:20 FILE
bat --diff FILE
Combined Patterns
Find → Search → Preview → Edit
rg -l "TODO" -t py | fzf --preview 'bat --color=always {}' | xargs $EDITOR
Find Files and View
bat $(fd -t f | fzf)
Search Log Files
rg "ERROR" app.log | fzf
Batch Rename
fd -e txt -x bat --style=header {}
Availability Check
Before using these tools in scripts, verify they are available:
command -v fd || echo "fd not found: brew install fd"
command -v rg || echo "rg not found: brew install ripgrep"
command -v fzf || echo "fzf not found: brew install fzf"
command -v bat || command -v batcat || echo "bat not found: brew install bat"
On Debian/Ubuntu fd may be fdfind and bat may be batcat. Check with which fd fdfind bat batcat.
When to Stick with Legacy Tools
grep: When the environment is guaranteed to lack rg (e.g., minimal Docker images, POSIX-only scripts).
find: In portable shell scripts (/bin/sh) where fd cannot be assumed.
cat: When piping raw bytes, using -A for non-printable inspection already provided by bat -A, or in pipelines where adding a pager would break things.
less/more: For arbitrary paging; bat uses them internally anyway.