How to Search for Text Inside Files in Linux
Find which files contain a word, and exactly where.
grep searches inside files; find searches for files. Confusing the two costs beginners a lot of time. For "where is this string used?", grep is the answer, and three flags cover almost every real use: -r to recurse, -n for line numbers, -i to ignore case.
Step by step
1 Search recursively with line numbers
$ grep -rn "DATABASE_URL" . Every match under the current directory, each prefixed with file:line. That prefix is what lets you jump straight to the place that matters.
2 Ignore case
$ grep -rni "error" logs/ Matches Error, ERROR and error alike. Log files rarely agree on capitalisation.
3 List only the file names
$ grep -rl "old-domain.com" . Useful when you care about which files are affected rather than the matches themselves — and it feeds neatly into a bulk replacement with xargs and sed.
4 Show surrounding context
$ grep -B2 -A5 "Exception" app.log Two lines before and five after each match. Indispensable for reading stack traces, where the error line alone tells you almost nothing.
5 Skip the noise
$ grep -rn "TODO" . --exclude-dir={node_modules,.git} --include="*.js" Excluding dependency directories turns a slow, cluttered search into an instant, readable one.
Tips worth knowing
- Install ripgrep (`rg`) if you can: it respects .gitignore, skips binaries automatically and is dramatically faster on large repositories.
- Searching for text with dots, brackets or dollars? Use grep -F to treat the pattern literally instead of as a regex.
- Count instead of listing with -c, and invert the match with -v to hide what you have already seen.
- Piping works too: any command output can be searched — `ps aux | grep nginx`, `journalctl -u app | grep -i timeout`.
Frequently asked questions
What is the difference between grep and find?
grep looks at the contents of files; find looks for files by name, size, date or type. "Which file mentions X" is grep; "where is the file called X" is find.
How do I search only certain file types?
grep -rn "text" . --include="*.py" restricts the search to Python files. Repeat --include for several patterns.
Why is my search so slow?
You are almost certainly scanning node_modules, .git or build directories. Exclude them with --exclude-dir, or use ripgrep, which does it by default.
How do I search compressed logs?
zgrep works exactly like grep but reads .gz files directly, with no need to decompress them first.
The commands behind it
Find lines matching a pattern in files or piped input — the workhorse of text search.
findLocate files anywhere in a directory tree by name, type, size, date — and act on them.
xargsTurn a list of items into command arguments — the glue between pipelines and commands.
sedStream-edit text: substitute, delete lines, and edit files in place with -i.
Concepts involved: Regular expression · Pipe (|)
Choosing between tools
More how-to guides
See how much space is left, and find out what is using it.
Extract a .tar.gz archiveUnpack tar.gz, tar.bz2, tar.xz and zip archives from the command line.
Free a port that is already in useFind which process holds a port and stop it cleanly.
Find and replace text in filesReplace text in one file or across a whole project, safely.