fd cheat sheet
replacesfindFind files with a simple syntax and sane defaults.
Basic Pattern Matching
fd <pattern> | Search current directory recursively for entries matching pattern (regex by default, smart case) |
fd <pattern> <dir> | Search for pattern starting from a specific root directory |
fd | List all files recursively in the current directory (no pattern = match everything) |
fd '^x.*rc$' | Use a full regular expression — here: filenames starting with 'x' and ending with 'rc' |
fd -g <glob> | Match using a glob pattern instead of a regular expression |
fd -p <pattern> | Match pattern against the full path, not just the filename |
fd -p -g <glob> | Match a glob pattern against the full path |
fd --and <pattern2> | Add an additional pattern that results must also match (logical AND) |
Case Sensitivity
fd <pattern> | Default smart case: case-insensitive unless pattern contains an uppercase letter |
fd -s <pattern> | Force case-sensitive matching |
fd -i <pattern> | Force case-insensitive matching regardless of uppercase in pattern |
Extension & Type Filters
fd -e <ext> | Find files with a specific file extension (no leading dot needed) |
fd -e <ext1> -e <ext2> | Find files matching any of multiple extensions |
fd -e <ext> <pattern> | Combine extension filter with a pattern |
fd -t f | Filter to regular files only (aliases: file) |
fd -t d | Filter to directories only (aliases: dir, directory) |
fd -t l | Filter to symbolic links only (alias: symlink) |
fd -t x | Filter to executable files only (alias: executable) |
fd -t e | Filter to empty files and directories only (alias: empty) |
fd -t s | Filter to sockets only (alias: socket) |
fd -t p | Filter to named pipes (FIFOs) only (alias: pipe) |
fd -t c | Filter to character devices only (alias: char-device) |
fd -t b | Filter to block devices only (alias: block-device) |
Hidden & Ignored Files
fd -H <pattern> | Include hidden files and directories (those starting with .) in results |
fd -I <pattern> | Do not respect .gitignore, .fdignore, or .ignore files |
fd -u <pattern> | Unrestricted: equivalent to -HI — search everything, no exclusions |
fd -E <glob> | Explicitly exclude entries matching a glob pattern |
fd -E '*.bak' | Exclude files by extension pattern |
fd --ignore-contain <name> | Ignore directories that contain a file or directory with the given name (e.g., CACHEDIR.TAG) |
fd --no-require-git | Respect .gitignore files even in directories that are not git repositories |
Depth Control
fd -d <n> | Limit search to at most n levels of directory depth |
fd --max-depth <n> | Long form of -d: limit maximum recursion depth |
fd --min-depth <n> | Only show results at least n directory levels deep |
fd --exact-depth <n> | Only show results at exactly n directory levels deep |
Advanced Filters
fd -S <size> | Filter by file size. Suffixes: k/m/g/t (SI) or ki/mi/gi/ti (binary). Prefix + for larger, - for smaller |
fd --changed-within <date|dur> | Show files modified more recently than a date or duration (alias: --changed-after) |
fd --changed-before <date|dur> | Show files modified before a date or duration |
fd -o <user:group> | Filter by owning user and/or group |
fd -L | Follow symbolic links (traverse them during search) |
fd --one-file-system | Do not cross filesystem boundaries (aliases: --mount, --xdev) |
fd --prune | Do not recurse into matching directories (prune them from traversal) |
Execution (-x and -X)
fd <pat> -x <cmd> | Execute command once per result in parallel; {} is replaced by the path |
fd <pat> -X <cmd> | Execute command once with ALL results passed as arguments (batch mode) |
fd -e jpg -x convert {} {.}.png | Convert each JPEG to PNG using ImageMagick; {.} strips the extension |
fd -e h -e cpp -x clang-format -i | Run clang-format in-place on every C/C++ source and header file |
fd -tf -x md5sum > checksums.txt | Compute MD5 checksums for all regular files in parallel and save to a file |
fd -e cpp -e h -X rg 'std::cout' | Search all C++ files for a pattern using ripgrep in one invocation |
fd -j 1 <pat> -x <cmd> | Run exec commands serially (1 thread) instead of in parallel |
fd <pat> -x cmd \; | Use \; to terminate the command template, allowing fd flags after the command |
fd --batch-size <n> -X <cmd> | Limit the number of results passed per -X invocation (useful for arg-length limits) |
fd -H '^\.DS_Store$' -tf -X rm ⚠ | Delete all .DS_Store files found recursively, including hidden directories |
fd -t f -e log --changed-before 30days -X rm ⚠ | Delete all log files older than 30 days — no confirmation, permanent deletion |
fd -t d -g node_modules -X rm -rf ⚠ | Recursively delete all node_modules directories — extremely destructive |
Exec Placeholder Syntax
{} | Full path of the matched entry |
{.} | Path without the file extension |
{/} | Basename only (filename without any leading path) |
{//} | Parent directory of the matched entry |
{/.} | Basename without the file extension |
Output & Display
fd -a <pattern> | Show absolute paths instead of paths relative to the current directory |
fd -l <pattern> | Long listing format showing permissions, size, modification time (like ls -l) |
fd -0 <pattern> | Separate results with NULL bytes instead of newlines (safe for filenames with spaces/newlines) |
fd -c always <pattern> | Force colored output even when piping (options: auto, always, never) |
fd --format <template> | Print results using a custom template (uses same placeholder syntax as --exec) |
fd --hyperlink <pattern> | Add OSC 8 terminal hyperlinks to output paths (options: auto, always, never) |
fd -q <pattern> | Quiet mode: suppress output, exit with code 0 if any match found, 1 if none |
Piping & Shell Integration
fd -e rs | xargs -0 wc -l | Pipe NULL-separated results to xargs for safe argument passing |
fd | tree --fromfile | Visualize fd results as a directory tree using the tree command |
fd --type file | fzf | Pipe fd results into fzf for interactive fuzzy selection |
export FZF_DEFAULT_COMMAND='fd --type file' | Set fd as fzf's default file listing backend (add to shell rc file) |
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" | Make Ctrl-T in fzf also use fd (set after FZF_DEFAULT_COMMAND) |
fd --gen-completions <shell> | Generate shell completion scripts (bash, zsh, fish, powershell) |
fd --base-directory <dir> | Execute fd as if run from the given directory (changes relative path output) |
fd --search-path <dir> | Supply additional search paths (can be repeated; alternative to positional path argument) |
Ignore File Configuration
~/.config/fd/ignore | Global ignore file (Linux/macOS) — glob patterns, one per line, always applied |
%APPDATA%\fd\ignore | Global ignore file path on Windows |
.fdignore | Per-project ignore file, same gitignore syntax — place at repo root or any parent |
.ignore | Generic ignore file also respected by ripgrep and ag (silver searcher) |
fd -I | Override all ignore files for a single run |
Killer recipes
Interactive file opener with fzf + bat preview
fd --type f --hidden --exclude .git | fzf --preview 'bat --style=numbers --color=always {}' | xargs -o $EDITORFind all non-ignored files, select interactively with fzf showing a syntax-highlighted preview via bat, then open the chosen file in $EDITOR. The -o flag in xargs keeps stdin for the editor.
Search file contents across a filtered set with ripgrep
fd -e ts -e tsx --exclude node_modules -X rg 'useEffect'Collect all TypeScript/TSX files (excluding node_modules) and pass them all at once to ripgrep — faster than rg alone when you want to pre-filter by name or location before searching contents.
Bulk image conversion in parallel
fd -e jpg -e jpeg -t f -x convert {} {.}.webpConvert every JPEG to WebP in parallel using ImageMagick. The {.} placeholder strips the extension so you get file.webp instead of file.jpg.webp. Parallelism is automatic with -x.
Find and view large files with eza details
fd -t f -S +50m | sort | xargs eza -lh --color=alwaysFind all files larger than 50 MB, then display them with eza's long listing for human-readable sizes, permissions, and timestamps in one readable table.
Safe stale log cleanup (dry-run first)
fd -t f -e log --changed-before 30days && fd -t f -e log --changed-before 30days -X rmFirst run lists all log files older than 30 days so you can review. The second command (after &&) actually deletes them. Split into two steps to avoid accidental deletion.
fzf directory jumper (replace cd)
cd "$(fd --type d --hidden --exclude .git | fzf)"Interactively fuzzy-find any directory (including hidden ones like .config) and cd into the selection. Wrap this in a shell function (e.g., named 'fcd') for daily use.