grep -r and -R: Recursive Directory Search
grep -r searches every file under a directory, recursing into subdirectories.
Scanning a whole tree for a forbidden string or a config key is a common CI check. -r walks the tree; -R does the same but follows symlinks.
What it does
grep -r (--recursive) reads all files under each given directory, recursing into subdirectories. grep -R (--dereference-recursive) does the same but follows symbolic links to directories. By default -r does not follow symlinks. With no path argument, GNU grep recurses the current directory.
Common usage
grep -r "TODO" src/
grep -rn "apiKey" .
grep -R "pattern" /etc/ # follows symlinked dirsOptions
| Flag | What it does |
|---|---|
| -r / --recursive | Recurse into directories (no symlink follow) |
| -R / --dereference-recursive | Recurse and follow symlinks |
| -n | Show line numbers (common with -r) |
| -l | List only the filenames that match |
| -I | Skip binary files entirely |
| --include / --exclude-dir | Limit which files or directories are searched |
In CI
On a checkout, scope the recursion with --exclude-dir=.git and --exclude-dir=node_modules, or it scans huge vendored trees and is slow. Use -R only when you actually need symlinks followed, since cycles can otherwise inflate the search.
Common errors in CI
"recursive directory loop" appears with -R when symlinks form a cycle; switch to -r or add --exclude-dir. Matches inside minified or binary files (grep prints "Binary file ... matches") usually mean you should add -I or --include to target source only. Slow runs are almost always an unbounded recursion into node_modules or .git.