Find all files containing a specific text (string) on Linux?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
To find all files containing a specific text string on Linux, use grep -Rl "search_string" . for a recursive search that prints matching file names. For faster results on source code trees, use rg -l "search_string" (ripgrep). Both commands search recursively from the current directory and handle most day-to-day scenarios.
grep: The Standard Tool
grep is installed on virtually every Linux system. The recursive flags and output options cover the majority of file search tasks.
Print Matching File Names Only
The -R flag searches recursively through all subdirectories. The -l flag tells grep to print only the file names that contain at least one match, not the matching lines themselves.
Print Matching Lines With Context
The -n flag adds line numbers to each match, which helps you jump directly to the relevant location in the file.
Case-Insensitive Search
The -i flag makes the search case-insensitive, so it matches Error, ERROR, error, and any other case variant.
Filter by File Extension
Exclude Directories
Excluding generated and dependency directories prevents noise and speeds up the search dramatically.
Useful grep Flag Combinations
| Flags | Purpose | Example |
-Rl | Recursive, file names only | grep -Rl "TODO" . |
-Rn | Recursive, with line numbers | grep -Rn "TODO" . |
-Rni | Recursive, line numbers, case-insensitive | grep -Rni "error" /var/log/ |
-Rnl | Recursive, file names only, case-insensitive | Not valid (use -Rli) |
-RnI | Recursive, line numbers, skip binary files | grep -RnI "config" . |
-Rc | Recursive, count matches per file | grep -Rc "TODO" . |
-Rw | Recursive, whole word match | grep -Rw "port" . |
ripgrep (rg): The Faster Alternative
ripgrep is significantly faster than grep on large codebases because it uses parallelism, respects .gitignore rules by default, and skips binary files automatically.
Basic Search
Filter by File Type
ripgrep has built-in file type awareness:
Filter by Glob Pattern
Show Context Around Matches
Combining find and grep
When the file selection criteria go beyond name patterns, find gives you more control:
The {} + syntax passes multiple file names to grep in batches, which is faster than {} \; (which spawns a new grep process per file).
The xargs Alternative
The -print0 and -0 flags use null bytes as delimiters, which handles file names containing spaces or special characters correctly.
Fixed Strings vs. Regular Expressions
By default, both grep and rg interpret the search pattern as a regular expression. Characters like ., *, [, (, and ? have special meaning:
Use fixed-string mode (-F) whenever you are searching for literal text that contains regex metacharacters.
Performance Comparison
| Tool | 100K files (warm cache) | .gitignore aware | Binary skip | Parallel |
grep -R | Slow (single-threaded) | No | Manual (-I flag) | No |
grep -R with excludes | Moderate | No | Manual | No |
rg | Fast | Yes (default) | Yes (default) | Yes |
find + grep | Moderate | No | Manual | No |
ag (The Silver Searcher) | Fast | Yes | Yes | Yes |
For large repositories, rg is typically 2-10x faster than grep -R due to parallelism and automatic exclusion of irrelevant files.
Searching Compressed Files
Log files are often compressed with gzip. Use zgrep to search without decompressing first:
Practical Recipes
Common Pitfalls
Forgetting -l when you only need file names produces a wall of matching lines that is hard to parse. Use -l for file lists and -n for line-level detail.
Treating the search pattern as a literal string when the tool interprets it as a regex causes unexpected matches. A search for user.name also matches username because . means "any character" in regex. Use -F for literal searches.
Searching large trees without excluding directories like node_modules, .git, vendor, or build wastes time and produces irrelevant results. Always add --exclude-dir flags (for grep) or rely on .gitignore (for rg).
Using find -exec grep {} \; instead of find -exec grep {} + spawns a separate grep process for every file, which is significantly slower on large file sets.
Searching binary files without the -I flag (grep) produces unreadable output and slows the search. ripgrep skips binary files by default, but grep does not.
Summary
- Use
grep -Rl "text" .to list files containing a string recursively. - Use
grep -Rnwhen you need line numbers and matching lines. - Use
rg(ripgrep) for faster searches that automatically respect.gitignoreand skip binary files. - Combine
findandgrepwhen you need to filter files by attributes like modification time, size, or ownership. - Use fixed-string mode (
-F) when the search text contains regex special characters. - Exclude dependency and generated directories to keep searches fast and relevant.
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.