NIX^:Linux & IT

Linux File & Directory Search

A comprehensive guide to find, grep, fd, and rg (ripgrep) for locating files and searching content.

intermediateupdated 2026-08-10PowerShell

Linux File & Directory Search Cheat Sheet

A comprehensive guide to find, grep, fd, and rg (ripgrep) for locating files and searching content.


Table of Contents

  1. find - Classic File Search
  2. grep - Content Search
  3. fd - Modern find Alternative
  4. rg (ripgrep) - Modern grep Alternative
  5. Combined Patterns & Workflows
  6. Windows findstr Equivalents

Basic Syntax

find [path] [options] [expression]

Finding Files by Name

# Find by exact name
find /path -name "filename.txt"

# Case-insensitive search
find /path -iname "filename.txt"

# Wildcards (must be quoted)
find . -name "*.ps1"
find . -name "*.log"
find . -name "Password_File*"

# Multiple patterns (OR logic)
find . -name "*.ps1" -o -name "*.sh" -o -name "*.py"

# Regex matching (full path)
find . -regex ".*\(\.ps1\|\.sh\)$"

# Extended regex
find . -regextype posix-extended -regex ".*(POWERSHELL_SCRIPT|Password_File|.*\.ps1)"

Finding by Type

# Files only
find . -type f

# Directories only
find . -type d

# Symbolic links
find . -type l

# Empty files
find . -type f -empty

# Empty directories
find . -type d -empty

Finding by Size

# Exactly 50MB
find . -size 50M

# Greater than 100MB
find . -size +100M

# Less than 1KB
find . -size -1k

# Between 1MB and 100MB
find . -size +1M -size -100M

# Size units: c(bytes), k(KB), M(MB), G(GB)

Finding by Time

# Modified in last 7 days
find . -mtime -7

# Modified more than 30 days ago
find . -mtime +30

# Modified exactly 1 day ago
find . -mtime 1

# Accessed in last 60 minutes
find . -amin -60

# Changed in last 24 hours (metadata)
find . -ctime -1

# Modified after a reference file
find . -newer reference_file.txt

# Modified between two dates
find . -newermt "2024-01-01" ! -newermt "2024-12-31"

Finding by Permissions & Ownership

# Exact permissions
find . -perm 644
find . -perm 755

# At least these permissions (all bits set)
find . -perm -644

# Any of these permissions (any bit set)
find . -perm /644

# World-writable files (security audit)
find . -perm -o=w -type f

# SUID/SGID files
find . -perm /4000    # SUID
find . -perm /2000    # SGID
find . -perm /6000    # Either

# By owner
find . -user username
find . -group groupname

# Files without owner (orphaned)
find . -nouser
find . -nogroup

Depth Control

# Maximum depth (don't go deeper than 2 levels)
find . -maxdepth 2 -name "*.txt"

# Minimum depth (skip current directory)
find . -mindepth 1 -name "*.txt"

# Exact depth (only level 3)
find . -mindepth 3 -maxdepth 3 -name "*.txt"

Excluding Paths

# Exclude a directory
find . -path "./node_modules" -prune -o -name "*.js" -print

# Exclude multiple directories
find . \( -path "./node_modules" -o -path "./.git" \) -prune -o -name "*.js" -print

# Using -not
find . -not -path "*/\.git/*" -name "*.py"

Actions

# Delete found files (DANGEROUS - test with -print first!)
find . -name "*.tmp" -delete

# Execute command on each file
find . -name "*.txt" -exec cat {} \;

# Execute with confirmation
find . -name "*.log" -ok rm {} \;

# More efficient execution (batched)
find . -name "*.txt" -exec cat {} +

# Print with null separator (for xargs)
find . -name "*.txt" -print0 | xargs -0 cat

# Custom output format
find . -name "*.txt" -printf "%p %s %T+\n"
# %p=path, %s=size, %T+=modification time

Complex Expressions

# AND (implicit)
find . -name "*.txt" -size +1M

# AND (explicit)
find . -name "*.txt" -a -size +1M

# OR
find . -name "*.txt" -o -name "*.md"

# NOT
find . ! -name "*.txt"
find . -not -name "*.txt"

# Grouping with parentheses
find . \( -name "*.txt" -o -name "*.md" \) -mtime -7

Basic Syntax

grep [options] pattern [file...]

Basic Pattern Matching

# Simple string search
grep "password" file.txt

# Search in multiple files
grep "password" *.txt

# Recursive search in directory
grep -r "password" /path/to/dir

# Case-insensitive
grep -i "password" file.txt

# Whole word only
grep -w "password" file.txt

# Fixed string (no regex interpretation)
grep -F "exact.string" file.txt

Regular Expressions

# Extended regex
grep -E "POWERSHELL_SCRIPT|Password_File|.*\.ps1" .

# Perl-compatible regex (PCRE)
grep -P "password\d{3}" file.txt

# Match beginning of line
grep "^start" file.txt

# Match end of line
grep "end$" file.txt

# Match any character
grep "p.ssword" file.txt

# Character class
grep "[Pp]assword" file.txt

# Negated character class
grep "[^0-9]" file.txt

# Quantifiers
grep -E "ab+" file.txt      # One or more
grep -E "ab*" file.txt      # Zero or more
grep -E "ab?" file.txt      # Zero or one
grep -E "a{3}" file.txt     # Exactly 3
grep -E "a{2,5}" file.txt   # 2 to 5 times

Output Control

# Show line numbers
grep -n "pattern" file.txt

# Show only matching part
grep -o "pattern" file.txt

# Count matches
grep -c "pattern" file.txt

# Show filename only
grep -l "pattern" *.txt

# Show files without matches
grep -L "pattern" *.txt

# Show context (before/after/both)
grep -B 3 "pattern" file.txt  # 3 lines before
grep -A 3 "pattern" file.txt  # 3 lines after
grep -C 3 "pattern" file.txt  # 3 lines both sides

# Suppress errors
grep -s "pattern" file.txt

# Quiet mode (exit code only)
grep -q "pattern" file.txt && echo "Found"

Recursive & File Filtering

# Recursive search
grep -r "pattern" /path

# Recursive following symlinks
grep -R "pattern" /path

# Include only certain files
grep -r --include="*.py" "pattern" .

# Exclude files
grep -r --exclude="*.log" "pattern" .

# Exclude directories
grep -r --exclude-dir=".git" "pattern" .
grep -r --exclude-dir={.git,node_modules,vendor} "pattern" .

Inverting & Combining

# Invert match (lines NOT matching)
grep -v "pattern" file.txt

# Multiple patterns (OR)
grep -E "pattern1|pattern2" file.txt
grep -e "pattern1" -e "pattern2" file.txt

# Multiple patterns from file
grep -f patterns.txt file.txt

# AND logic (all patterns must match)
grep "pattern1" file.txt | grep "pattern2"
grep -P "(?=.*pattern1)(?=.*pattern2)" file.txt

Binary & Special Files

# Treat binary as text
grep -a "pattern" binary_file

# Skip binary files
grep -I "pattern" *

# Search compressed files
zgrep "pattern" file.gz
bzgrep "pattern" file.bz2
xzgrep "pattern" file.xz

3. fd - Modern find Alternative

Installation: apt install fd-find (Debian/Ubuntu), brew install fd (macOS), cargo install fd-find Note: On Debian/Ubuntu, the binary is fdfind

Basic Usage

# Simple search (case-insensitive by default)
fd pattern

# Search in specific directory
fd pattern /path/to/dir

# Case-sensitive search
fd -s Pattern

# Exact match
fd -g "exact_filename.txt"

# Show full path
fd -a pattern

File Type Filtering

# Files only
fd -t f pattern

# Directories only
fd -t d pattern

# Symbolic links
fd -t l pattern

# Executables
fd -t x pattern

# Empty files/directories
fd -t e pattern

# Specific extension
fd -e txt
fd -e py
fd -e ps1

# Multiple extensions
fd -e txt -e md -e rst

Advanced Patterns

# Regex (default)
fd ".*\.(ps1|sh|py)$"

# Glob pattern
fd -g "*.ps1"
fd -g "Password_File*"

# Multiple patterns (Windows findstr equivalent)
fd -g "POWERSHELL_SCRIPT" . && fd -g "Password_File*" . && fd -e ps1
# Or using regex:
fd "(POWERSHELL_SCRIPT|Password_File|.*\.ps1)"

# Hidden files included
fd -H pattern

# Ignored files included (.gitignore)
fd -I pattern

# Both hidden and ignored
fd -HI pattern

Filtering & Exclusions

# Exclude pattern
fd -E "*.log" pattern
fd -E node_modules pattern

# Multiple exclusions
fd -E node_modules -E .git -E target pattern

# Use .gitignore rules (default)
fd pattern

# Ignore .gitignore
fd -I pattern

# Exclude directories
fd -E ".git/" -E "node_modules/" pattern

Size & Time Filters

# Size filters
fd -S +1M           # Larger than 1MB
fd -S -100k         # Smaller than 100KB
fd -S +1M -S -100M  # Between 1MB and 100MB

# Time filters
fd --changed-within 1d    # Changed in last day
fd --changed-within 2h    # Changed in last 2 hours
fd --changed-before 1w    # Changed more than 1 week ago

Depth Control

# Maximum depth
fd -d 2 pattern

# Exact depth
fd --min-depth 2 --max-depth 2 pattern

Execution

# Execute command on each result
fd -e txt -x cat {}

# Execute with placeholders
fd -e txt -x echo "File: {}" "Dir: {//}" "Name: {/}" "Base: {.}"
# {} = full path
# {//} = parent directory
# {/} = filename
# {.} = filename without extension
# {/.} = filename without extension, no path

# Parallel execution (default)
fd -e txt -x wc -l {}

# Batch execution
fd -e txt -X cat {}

# Delete files
fd -e tmp -X rm {}

Output Formatting

# Null separator (for xargs)
fd -0 pattern | xargs -0 command

# Absolute paths
fd -a pattern

# Color control
fd --color=always pattern | less -R
fd --color=never pattern

4. rg (ripgrep) - Modern grep Alternative

Installation: apt install ripgrep (Debian/Ubuntu), brew install ripgrep (macOS), cargo install ripgrep

Basic Usage

# Simple search (recursive by default)
rg "pattern"

# Search specific file
rg "pattern" file.txt

# Search specific directory
rg "pattern" /path/to/dir

# Case-insensitive
rg -i "pattern"

# Case-sensitive (default)
rg -s "pattern"

# Smart case (insensitive unless uppercase present)
rg -S "pattern"

Pattern Types

# Regex (default)
rg "POWERSHELL_SCRIPT|Password_File|.*\.ps1"

# Fixed string (literal)
rg -F "exact.string"

# Word boundary
rg -w "word"

# Whole line
rg -x "entire line must match"

# Multiline
rg -U "pattern\nacross\nlines"

# PCRE2 regex
rg -P "(?i)password(?=.*\d)"

File Type Filtering

# By type
rg -t py "pattern"        # Python files
rg -t js "pattern"        # JavaScript files
rg -t sh "pattern"        # Shell scripts

# Multiple types
rg -t py -t js "pattern"

# List available types
rg --type-list

# Exclude type
rg -T js "pattern"

# Custom type definition
rg --type-add 'config:*.{conf,cfg,ini}' -t config "pattern"

# By glob
rg -g "*.py" "pattern"
rg -g "*.{py,js,ts}" "pattern"

# Exclude by glob
rg -g "!*.log" "pattern"
rg -g "!node_modules/**" "pattern"

Output Control

# Line numbers (default on)
rg -n "pattern"

# No line numbers
rg -N "pattern"

# Show only filenames
rg -l "pattern"

# Show files without matches
rg --files-without-match "pattern"

# Count matches per file
rg -c "pattern"

# Only matching text
rg -o "pattern"

# Context lines
rg -B 3 "pattern"  # 3 before
rg -A 3 "pattern"  # 3 after
rg -C 3 "pattern"  # 3 both

# Replace matches
rg "pattern" -r "replacement"

# Show column number
rg --column "pattern"

Hidden & Ignored Files

# Search hidden files
rg --hidden "pattern"

# Ignore .gitignore
rg --no-ignore "pattern"

# Ignore .ignore and .gitignore
rg --no-ignore-vcs "pattern"

# Everything (hidden + all ignore files)
rg -uuu "pattern"
# -u = --no-ignore
# -uu = --no-ignore --hidden
# -uuu = --no-ignore --hidden --binary

Performance Options

# Follow symlinks
rg -L "pattern"

# Limit results
rg -m 5 "pattern"

# Memory map (faster for large files)
rg --mmap "pattern"

# Thread count
rg -j 4 "pattern"

Advanced Features

# JSON output
rg --json "pattern"

# Null separator
rg -0 -l "pattern" | xargs -0 command

# Stats
rg --stats "pattern"

# Debug regex
rg --debug "pattern"

# Trace file searching
rg --trace "pattern"

# Search binary files
rg -a "pattern"

# Search compressed files (requires preprocessing)
zcat file.gz | rg "pattern"

5. Combined Patterns & Workflows

Find Files Then Search Content

# Using find + grep
find . -name "*.py" -exec grep -l "import os" {} \;

# Using find + xargs (more efficient)
find . -name "*.py" -print0 | xargs -0 grep -l "import os"

# Using fd + rg
fd -e py -x rg -l "import os" {}

# Find and search in one command
fd -e py --exec rg "import os" {}

Complex Search Scenarios

# Find large log files modified today
find . -name "*.log" -size +10M -mtime 0
fd -e log -S +10M --changed-within 1d

# Find all scripts and search for passwords
find . \( -name "*.sh" -o -name "*.py" -o -name "*.ps1" \) -exec grep -i "password" {} +
fd -e sh -e py -e ps1 -x rg -i "password" {}

# Find empty directories and delete
find . -type d -empty -delete
fd -t d -t e -X rmdir {}

# Find duplicate filenames
find . -type f -printf "%f\n" | sort | uniq -d

# Security audit: world-writable files
find / -type f -perm -o=w 2>/dev/null

Creating File Lists

# All Python files to a list
find . -name "*.py" > python_files.txt
fd -e py > python_files.txt

# Files with specific content
grep -r -l "TODO" . > todo_files.txt
rg -l "TODO" > todo_files.txt

# Sorted by modification time
find . -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f2-

6. Windows findstr Equivalents

The Windows command:

findstr "POWERSHELL_SCRIPT|Password_File|*.ps1"

Equivalent in Linux Tools

TaskLinux Command
Search file namesfind . -regex ".*\(POWERSHELL_SCRIPT|Password_File|.*\.ps1\)"
Search file names (fd)fd "(POWERSHELL_SCRIPT|Password_File|.*\.ps1)"
Search file contentgrep -rE "POWERSHELL_SCRIPT|Password_File" --include="*.ps1" .
Search file content (rg)rg "POWERSHELL_SCRIPT|Password_File" -t ps1
Combined (names + content)See below

Combined Search (Names AND Content)

# Find files matching name patterns, then search inside them
find . \( -name "*POWERSHELL*" -o -name "*Password_File*" -o -name "*.ps1" \) \
  -exec grep -l "sensitive_pattern" {} \;

# Using fd + rg
fd "(POWERSHELL_SCRIPT|Password_File|.*\.ps1)" -x rg -l "sensitive_pattern" {}

# Find .ps1 files containing specific patterns
rg -t ps1 "POWERSHELL_SCRIPT|Password_File"

Quick Reference Card

Taskfindfdgreprg
Find by namefind . -name "*.txt"fd -e txtN/AN/A
Find files onlyfind . -type ffd -t fN/AN/A
Case insensitivefind . -inamedefaultgrep -irg -i
Regex-regexdefaultgrep -Edefault
Recursivedefaultdefaultgrep -rdefault
Exclude dir-path X -prune-E dir/--exclude-dir-g "!dir/"
Execute-exec cmd {} \;-x cmd {}N/AN/A
Hidden filesdefault-Hdefault--hidden
Size filter-size +10M-S +10MN/AN/A
Time filter-mtime -7--changed-within 7dN/AN/A

Pro Tips

  1. Always quote patterns with wildcards to prevent shell expansion
  2. Use -print0 / -0 for filenames with spaces
  3. Test destructive commands with -print or echo first
  4. fd and rg respect .gitignore by default - use -I/--no-ignore to override
  5. Combine tools for complex workflows: fd ... | xargs rg ...
  6. Use -- to separate options from patterns starting with -
On this page

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.