Swap ls, cat, find and grep for eza, bat, fd and ripgrep
Install eza, bat, fd and ripgrep, learn the side-by-side commands and flag differences, and alias them without breaking your scripts.
Updated
in short
Install eza, bat, fd and ripgrep, alias ls and cat in your interactive rc file, and call fd and rg by their own names. Leave scripts on ls, cat, find and grep, because several flags mean different things.
These four tools cover the same jobs as the classic commands with different defaults: colour and Git status in listings, syntax highlighting when reading files, and searches that skip hidden and .gitignored files. Those defaults are what make them faster to type, and also why they are not drop-in replacements for scripts.
This guide installs all four, shows the equivalent commands side by side, points out the flags that differ, and sets up aliases that only apply in your interactive shell.
Tools used
eza
Modern replacement for ls with colors, Git integration, tree view, and extended file metadata display.
23.7kRustbat
A cat clone with syntax highlighting, Git integration, and automatic paging for viewing files in the terminal.
61.0kRustfd
Fast filesystem search tool that replaces find with regex patterns and smart defaults
44.9kRustripgrep
Fast line-oriented regex search tool that recursively searches directories with automatic gitignore and binary file filtering
69.5kRust
Before you start
- A package manager such as Homebrew, apt, dnf or pacman
~/.local/binon yourPATHif you are on Debian or Ubuntu (for the symlinks in step 2)
Steps
Step 1: Install the four tools
All four are packaged by Homebrew and most Linux distributions. On Debian and Ubuntu the fd package is called
fd-find, and eza is in the archive from Debian 13 and Ubuntu 24.04; on older releases use the apt repository described in eza'sINSTALL.md. The ripgrep binary isrg.shbrew install eza bat fd ripgrepshsudo apt install eza bat fd-find ripgrepshsudo pacman -S eza bat fd ripgrepStep 2: Fix the binary names on Debian and Ubuntu
Debian and Ubuntu install fd as
fdfind, becausefdis taken by another package, and some releases install bat asbatcatfor the same reason. Symlink them into~/.local/binso the commands in this guide work. Skip this on other systems.shmkdir -p ~/.local/bin ln -s "$(which fdfind)" ~/.local/bin/fd ln -s /usr/bin/batcat ~/.local/bin/bat # only if `bat` is not foundsheza --version && bat --version && fd --version && rg --versionStep 3: List files with eza
Most short listing flags carry over:
-l,-a,-1,-R,-r. Sizes in-loutput are already human-readable. eza adds--gitfor per-file Git status and--treewith--levelfor depth.Watch three flags.
-tpicks which timestamp to show and needs a value, sols -ltbecomeseza -l -s modified -r(eza sorts oldest first,-rflips it).-hadds a header row instead of human-readable sizes. And-ssorts by a named field rather than showing block sizes.sh# ls -la eza -la # ls -lt (newest first) eza -l -s modified -r # tree -L 2, skipping gitignored files eza --tree --level=2 --git-ignore # long listing with a Git status column eza -l --gitStep 4: Read files with bat
bat fileprints with syntax highlighting, line numbers and Git change markers, and pipes long output through a pager. When its output goes to a pipe or a file, bat prints the plain contents likecat, sobat a b > cstill concatenates.-pdrops the decorations,-ppalso turns off paging,-Ashows non-printable characters likecat -A, and-lsets the language for stdin or unknown extensions.shbat src/main.rs bat -pp config.toml # plain, no pager bat -A script.sh # show tabs, newlines, other control characters curl -s https://example.com | bat -l htmlStep 5: Find files with fd
fd PATTERNmatches a regular expression anywhere in the file name, sofd reportbehaves likefind . -iname '*report*'. Search is case-insensitive unless the pattern contains an uppercase letter. Use-efor an extension,-gfor an exact glob,-t for-t dfor files or directories, and-pto match against the full path.The main difference from
find: fd skips hidden files and anything matched by.gitignorewhen it is inside a Git repository. Add-Hfor hidden files,-Ifor ignored files, or-ufor both.sh# find . -name '*.md' fd -e md # find . -type f -name 'Dockerfile' fd -t f -g Dockerfile # include hidden and ignored files, like find does fd -u '\.env$'sh# find . -name '*.zip' -exec unzip {} \; fd -e zip -x unzip # one command with all results, like find ... -exec cmd {} + fd -e md -X wc -lStep 6: Search file contents with ripgrep
rg PATTERNsearches the current directory recursively, so there is no-r. It skips gitignored, hidden and binary files;-udrops the ignore files,-uuadds hidden files and-uuusearches everything, likegrep -r. Line numbers show by default in a terminal.Patterns use Rust regex syntax, which is close to
grep -E: alternation isa|b, not thea\|bof default grep. Backreferences and look-around need-P(PCRE2), which depends on how your copy was built. Familiar flags still work:-i,-w,-l,-v,-F,-c.-Sturns on smart case, and-tand-gfilter by file type or glob.sh# grep -rn 'TODO' . rg TODO # grep -rl --include='*.py' 'import requests' . rg -l -t py 'import requests' # literal string with regex characters rg -F 'user.id == 0' # exclude a directory by glob rg -g '!vendor/' 'func main'Step 7: Alias them in your interactive shell only
Put aliases in
~/.bashrc,~/.zshrcor fish'sconfig.fish, which interactive shells read and scripts do not. bash does not expand aliases in non-interactive scripts unless they runshopt -s expand_aliases, so scripts keep calling the reallsandcat.Alias
lsandcatonly.findandgreptake different arguments from fd and rg, so aliasing them breaks muscle memory in both directions; typefdandrginstead. To reach the original command past an alias, runcommand lsor\ls.sh# ~/.bashrc or ~/.zshrc alias ls='eza' alias ll='eza -l --git' alias la='eza -la' alias lt='eza --tree --level=2' alias cat='bat --paging=never'fish# ~/.config/fish/config.fish alias ls 'eza' alias ll 'eza -l --git' alias cat 'bat --paging=never'
Keep scripts on the originals
ls,cat,findandgrepare on every POSIX system; eza, bat, fd and rg are not, so shipped scripts and CI images should not depend on them.- fd and rg silently skip hidden and gitignored files. A script that must see every file needs
find/grep, orfd -uandrg -uuu. - eza with no path argument reads file names from stdin when stdin is not a terminal. In cron jobs or pipelines, pass
.explicitly. - fd
-xruns commands in parallel and in no fixed order. Use--threads=1or-Xif order matters. - rg exits 0 on a match, 1 on no match and 2 on an error, the same as grep, so
if rg -q ...works in scripts.
Troubleshooting
fd: command not foundon Debian or Ubuntu: the binary isfdfind. Create the symlink from step 2.- bat opens a pager when you only wanted output: pass
--paging=never, or setBAT_PAGING=neverto make it permanent. eza -ltfails with an error about--time <FIELD>: in eza-tselects which timestamp to show. Sort with-s modified -rinstead.- rg or fd misses a file you can see: it is hidden or matched by
.gitignore,.ignoreor.rgignore/.fdignore. Add-u. - rg prints
backreferences are not supported: add-Pto use PCRE2, if your build includes it (rg --versionlists+pcre2).
Also worth a look
- lsdAnother ls replacement with colours, icons and a tree view.
- exaThe project eza was forked from; exa is unmaintained and points users to eza.
- bfsBreadth-first find that keeps find's syntax, for when you want find's flags rather than fd's.
- rgaWraps ripgrep to search inside PDFs, Office documents, archives and other formats.
FAQ
- Can I alias grep to rg?
- You can, but rg's defaults and some flags differ from grep's, so commands copied from documentation may behave differently. Typing `rg` keeps both available.
- Is bat safe to use as cat in pipelines?
- Yes. When output is not a terminal, bat prints the plain file contents with no line numbers, colours or pager.
- Why does fd not find my .env file?
- fd skips hidden files by default. Use `fd -H '\.env'`, and add `-I` if the file is also in `.gitignore`.