React SME Cookbook
All FAQs

Search Documentation

Search across all documentation pages

linuxgrepfindregexsearch

Search & Regex

Find files by name, search text inside files, and use regex patterns — the core skill for navigating any codebase from the terminal.

Recipe

Quick-reference recipe card — copy-paste ready.

# Find files by name
find . -name "*.tsx" -type f
find . -name "page.tsx" -path "*/app/*"
 
# Search text inside files
grep -r "useState" src/
grep -rn "TODO" --include="*.ts" .
 
# Faster alternative (ripgrep)
rg "useState" src/
rg "TODO" -t ts
 
# Find and replace across files
sed -i '' 's/oldFunction/newFunction/g' src/**/*.ts

When to reach for this: When you need to find a file, locate where a function is used, search for a pattern across the codebase, or do bulk find-and-replace.

Working Example

# "Where is this component defined?"
rg "export.*function Header" --include="*.tsx"
# or
grep -rn "export.*function Header" --include="*.tsx" src/
 
# "Which files import this module?"
rg "from.*@/components/Button" -l
# -l = files only, no matching lines
 
# "Find all TODO comments with context"
rg "TODO|FIXME|HACK" -t ts -t tsx -C 2
# -C 2 = show 2 lines of context above and below
 
# "Find large files in the project"
find . -type f -size +1M -not -path "./node_modules/*" -not -path "./.next/*"

What this demonstrates:

  • grep -rn for recursive search with line numbers
  • rg (ripgrep) is significantly faster and auto-ignores .gitignore patterns
  • -l flag shows only filenames, useful for piping to other commands
  • find combined with -not -path to exclude directories

Deep Dive

find — Locate Files by Name, Type, Size, Date

# Basic name search (case-sensitive)
find . -name "layout.tsx"
 
# Case-insensitive
find . -iname "readme*"
 
# By file type
find . -type f                   # files only
find . -type d                   # directories only
 
# By extension pattern
find . -name "*.test.ts"
find . -name "*.md" -o -name "*.mdx"  # OR
 
# Exclude directories
find . -name "*.ts" -not -path "*/node_modules/*" -not -path "*/.next/*"
 
# By modification time
find . -name "*.tsx" -mtime -1       # modified in last 24 hours
find . -name "*.tsx" -mmin -60       # modified in last 60 minutes
find . -name "*.tsx" -newer reference.txt  # newer than a file
 
# By size
find . -type f -size +500k           # larger than 500KB
find . -type f -size -1k             # smaller than 1KB
find . -type f -empty                # empty files
 
# Execute a command on results
find . -name "*.test.ts" -exec wc -l {} \;
find . -name "*.log" -exec rm {} \;
find . -name "*.tsx" -exec grep -l "useState" {} \;
 
# Using xargs (often faster for many files)
find . -name "*.ts" | xargs grep "deprecated"
find . -name "*.tmp" -print0 | xargs -0 rm  # handle spaces in filenames

grep — Search Text Inside Files

# Basic recursive search
grep -r "pattern" directory/
 
# With line numbers
grep -rn "useState" src/
 
# Case insensitive
grep -rni "error" src/
 
# Only filenames (no matching lines)
grep -rl "useEffect" src/components/
 
# Invert match (lines NOT matching)
grep -v "node_modules" file.txt
 
# Count matches per file
grep -rc "import" src/ | sort -t: -k2 -rn | head -10
 
# Filter by file extension
grep -rn "fetchData" --include="*.ts" --include="*.tsx" .
grep -rn "TODO" --include="*.{ts,tsx}" .
 
# Exclude directories
grep -rn "console.log" --exclude-dir=node_modules --exclude-dir=.next .
 
# Show context around matches
grep -rn "error" -A 3 src/    # 3 lines After
grep -rn "error" -B 2 src/    # 2 lines Before
grep -rn "error" -C 2 src/    # 2 lines Context (both)
 
# Match whole words only
grep -rw "use" src/            # matches "use" but not "useState"
 
# Multiple patterns
grep -rn -e "useState" -e "useEffect" src/

ripgrep (rg) — Modern grep Replacement

# Install
# macOS: brew install ripgrep
# Ubuntu: sudo apt install ripgrep
 
# Basic search (auto-ignores .gitignore patterns)
rg "pattern" src/
 
# Filter by file type
rg "useState" -t tsx
rg "TODO" -t ts -t tsx
 
# Only filenames
rg "useEffect" -l
 
# Files NOT matching
rg "useEffect" --files-without-match -t tsx
 
# Fixed string (no regex interpretation)
rg -F "array.map((item) =>" src/
 
# Multiline search
rg -U "export default function.*\n.*return" src/
 
# Replace (preview — does not modify files)
rg "oldName" -r "newName"
 
# Show stats
rg "TODO" --stats
 
# Search hidden files too
rg "SECRET" --hidden
 
# Glob patterns
rg "fetch" -g "*.ts" -g "!*.test.ts"  # ts files but not test files

Regex Patterns — Quick Reference

# Anchors
^start        # line starts with "start"
end$          # line ends with "end"
^exact$       # entire line is "exact"
 
# Character classes
[abc]         # a, b, or c
[a-z]         # lowercase letter
[0-9]         # digit
[^abc]        # NOT a, b, or c
.             # any single character
 
# Quantifiers
a*            # zero or more a's
a+            # one or more a's
a?            # zero or one a
a{3}          # exactly 3 a's
a{2,5}        # 2 to 5 a's
 
# Groups and alternation
(foo|bar)     # foo or bar
(abc)+        # one or more "abc" sequences
 
# Common shortcuts
\d            # digit [0-9]        (extended regex)
\w            # word char [a-zA-Z0-9_]
\s            # whitespace
\b            # word boundary
 
# Escape special characters
\.            # literal dot
\(            # literal parenthesis

Practical Regex Examples for Codebases

# Find React component definitions
rg "export (default )?(function|const) [A-Z]\w+"
 
# Find all hook calls
rg "use[A-Z]\w+\(" -t tsx
 
# Find console.log statements (but not console.error/warn)
rg "console\.log\(" src/
 
# Find TODO with author
rg "TODO\([^)]+\):" src/
 
# Find hardcoded URLs
rg "https?://[^\s\"')\]>]+" src/
 
# Find empty catch blocks
rg -U "catch\s*\([^)]*\)\s*\{\s*\}" src/
 
# Find imports from a specific package
rg "from ['\"]react['\"]" src/
 
# Find CSS color hex codes
rg "#[0-9a-fA-F]{3,8}\b" src/
 
# Find potential API keys (basic pattern)
rg "['\"][A-Za-z0-9_]{20,}['\"]" --include="*.ts" src/
 
# Find duplicate adjacent words (typos)
rg "\b(\w+)\s+\1\b" docs/

sed — Find and Replace in Files

# Replace in a single file (macOS — '' is required)
sed -i '' 's/oldText/newText/g' file.tsx
 
# Replace in a single file (Linux)
sed -i 's/oldText/newText/g' file.tsx
 
# Preview without modifying (works on both)
sed 's/oldText/newText/g' file.tsx
 
# Replace across multiple files
find src -name "*.tsx" -exec sed -i '' 's/OldComponent/NewComponent/g' {} \;
 
# Replace with regex
sed -i '' 's/className="text-[a-z]*"/className="text-base"/g' file.tsx
 
# Delete lines matching a pattern
sed -i '' '/console\.log/d' src/app/page.tsx
 
# Replace only on lines matching a condition
sed -i '' '/import/s/react/react-dom/' file.tsx

awk — Extract and Transform Text

# Print specific columns
ps aux | awk '{print $1, $2, $11}'     # user, PID, command
 
# Sum a column
wc -l src/**/*.tsx | awk '{sum += $1} END {print sum " total lines"}'
 
# Filter by condition
df -h | awk '$5 > "80%"'               # disks over 80% full
 
# Print lines between patterns
awk '/START/,/END/' file.txt
 
# Count unique values
git log --format="%an" | sort | uniq -c | sort -rn

Gotchas

Things that will bite you. Each gotcha includes what goes wrong, why it happens, and the fix.

  • grep searches node_modules — Without --exclude-dir, grep searches everything and takes forever. Fix: Use rg (auto-respects .gitignore) or add --exclude-dir=node_modules.

  • find returns too many results — Searching from / or without excluding directories. Fix: Always scope your search: find src/ ... and use -not -path.

  • sed differences between macOS and Linux — macOS sed requires -i '' (empty string for backup extension), Linux doesn't. Fix: Use sed -i '' 's/.../.../' file on macOS or install GNU sed: brew install gnu-sed.

  • Regex metacharacters in search strings — Searching for literal [, ., ( etc. without escaping. Fix: Use grep -F or rg -F for fixed (non-regex) strings.

  • Missing results with basic grep regex — Some patterns like \d, +, \w need extended regex. Fix: Use grep -E (extended) or grep -P (Perl-compatible) for advanced patterns.

Alternatives

Other ways to solve the same problem — and when each is the better choice.

AlternativeUse WhenDon't Use When
rg (ripgrep)Fast codebase search, respects .gitignoreNot installed on the server
ag (silver searcher)Similar to rg, already installedrg is available (rg is generally faster)
fdModern find replacement with simpler syntaxScripting that needs POSIX find compatibility
IDE search (Cmd+Shift+F)Visual context, quick navigation to resultsScripting, automation, or remote servers
fzfInteractive fuzzy finding of files and contentExact pattern matching needed

FAQs

What is the difference between grep and rg (ripgrep)?
  • rg is significantly faster, especially on large codebases
  • rg auto-ignores files listed in .gitignore
  • grep is pre-installed everywhere; rg may need to be installed separately
How do I search for a literal string that contains regex special characters?
grep -F "array.map((item) =>" src/
# or
rg -F "array.map((item) =>" src/
  • The -F flag treats the pattern as a fixed string, not a regex
How do I find all files modified in the last hour?
find . -name "*.tsx" -mmin -60
  • -mmin -60 means modified less than 60 minutes ago
  • -mtime -1 means modified in the last 24 hours
How do I exclude node_modules from my searches?
  • With grep: grep -rn "pattern" --exclude-dir=node_modules .
  • With find: find . -name "*.ts" -not -path "*/node_modules/*"
  • With rg: automatic (respects .gitignore)
What is the difference between grep -E and grep -P?
  • -E enables extended regex (supports +, ?, |, () without escaping)
  • -P enables Perl-compatible regex (supports \d, \w, \b, lookaheads)
  • Use -E for most cases; use -P when you need advanced patterns
Gotcha: Why does sed -i behave differently on macOS vs Linux?
  • macOS sed requires an empty string for in-place editing: sed -i '' 's/old/new/g' file
  • Linux sed does not: sed -i 's/old/new/g' file
  • Install GNU sed on macOS with brew install gnu-sed for consistent behavior
How do I find all React component definitions in a codebase?
rg "export (default )?(function|const) [A-Z]\w+" -t tsx
  • This matches both function declarations and arrow function components
How do I do a find-and-replace across multiple files?
find src -name "*.tsx" -exec sed -i '' 's/OldName/NewName/g' {} \;
  • Always preview first with sed 's/OldName/NewName/g' file.tsx (no -i)
Gotcha: My grep regex with \d is not matching digits. Why?
  • Basic grep does not support \d; use [0-9] instead
  • Or use extended/Perl regex: grep -P "\d+" file or grep -E "[0-9]+" file
How do I count the number of matches per file?
grep -rc "import" src/ | sort -t: -k2 -rn | head -10
  • -c prints a count per file instead of matching lines
How do I find empty catch blocks in TypeScript files?
rg -U "catch\s*\([^)]*\)\s*\{\s*\}" src/
  • -U enables multiline matching
  • Empty catch blocks silently swallow errors and should be avoided
How can I search for TypeScript type definitions across the project?
rg "^(export )?(type|interface) \w+" -t ts
  • Matches both type and interface declarations
  • Add -l to list only the file paths