Search Files for Text with grep

grepsearchtext
4 min read

Quick Answer

The grep command searches files for a pattern and prints every matching line with its filename. This script wraps grep -rn — recursive search with line numbers — so you can locate any string across an entire directory tree in a single command. Without grep, tracking down a hardcoded credential, a renamed function, or a specific log message across hundreds of files means opening each file manually. Running grep -rn "TODO" /var/www/html --include="*.php" scans every PHP file under /var/www/html and returns the filename, line number, and the matched line for every result. The -i flag makes the search case-insensitive; --color=auto highlights each match in the terminal output. Works on Ubuntu 22.04 LTS, Debian 12, Fedora 39, CentOS 9, and macOS Ventura — grep is pre-installed on every POSIX-compliant system. No packages needed. Run directly in your terminal.

The Script

This covers the most useful grep patterns. Paste the one you need and change the search term and path.

bash
#!/bin/bash # Search files for text — grep reference # Replace KEYWORD and SEARCH_DIR with your values # # USAGE: ./grep-search.sh # REQUIRES: grep (pre-installed on Linux/macOS) KEYWORD="TODO" # ← what to search for SEARCH_DIR="$HOME" # ← where to search FILE_TYPE="*.txt" # ← file types to include echo "Searching for '$KEYWORD' in $SEARCH_DIR..." echo "────────────────────────────────────────" grep -rn "$KEYWORD" "$SEARCH_DIR" \ --include="$FILE_TYPE" \ --color=auto COUNT=$(grep -rc "$KEYWORD" "$SEARCH_DIR" \ --include="$FILE_TYPE" 2>/dev/null \ | grep -v ":0$" | wc -l) echo "────────────────────────────────────────" echo "Found in $COUNT file(s)"

What this does

grep -rn searches recursively (-r) through all subdirectories and shows line numbers (-n) for each match. --include filters to a specific file type. --color=auto highlights your keyword in the output so it's easy to scan.

Step-by-Step: The Commands You'll Use Daily

Step 1 — Search a single file

The simplest form: search one file for one term.

bash
grep "ERROR" /var/log/app.log

Every line containing "ERROR" prints to your terminal. Nothing else. Fast.

Step 2 — Add line numbers (-n)

bash
grep -n "ERROR" /var/log/app.log # Output: # 42: ERROR: connection refused # 87: ERROR: disk write failed

Now you know exactly which line to jump to in your editor.

Step 3 — Search recursively across a whole folder (-r)

bash
grep -rn "TODO" ~/projects/ # Output includes filename, line number, and the matching line: # ~/projects/api/routes.py:14: # TODO: add auth check # ~/projects/api/models.py:88: # TODO: validate input

-rn is your default combination

You'll type grep -rn "keyword" /path more than almost any other command. The r searches all subdirectories, the n gives you line numbers. Memorise this one first.

Step 4 — Filter by file type (--include)

bash
# Search only .log files grep -rn "CRITICAL" /var/log --include="*.log" # Search only Python files grep -rn "import os" ~/projects --include="*.py" # Search multiple file types grep -rn "api_key" . --include="*.py" --include="*.env"

Step 5 — Case insensitive search (-i)

bash
# Matches: error, ERROR, Error, eRrOr grep -rni "error" /var/log --include="*.log"

grep Flags Reference

FlagWhat it doesExample
-rRecursive — search all subdirectoriesgrep -r "term" /folder
-nShow line numbers in outputgrep -n "term" file.txt
-iCase insensitive matchgrep -i "error" file.log
-lShow only filenames, not the matching linesgrep -rl "TODO" ~/projects
-cCount of matching lines per filegrep -rc "error" /var/log
-vInvert — show lines that do NOT matchgrep -v "DEBUG" app.log
-wMatch whole words onlygrep -w "log" file.txt
-A 3Show 3 lines after each match (context)grep -A 3 "ERROR" app.log
-B 3Show 3 lines before each matchgrep -B 3 "ERROR" app.log
--includeLimit search to matching filenamesgrep -r "term" . --include="*.py"
--excludeSkip files matching patterngrep -r "term" . --exclude="*.min.js"

Real-World Examples

Find all TODO comments across a codebase

bash
grep -rn "TODO\|FIXME\|HACK" ~/projects --include="*.py"

Scan logs for errors in the last hour

bash
# Find ERROR lines and show 2 lines of context around each grep -n -A 2 -B 2 "ERROR" /var/log/app.log

Check if a config file contains a specific setting

bash
# Returns the line if found, nothing if not grep "PermitRootLogin" /etc/ssh/sshd_config

Count how many files in a project contain a term

bash
# -l lists filenames only, wc -l counts them grep -rl "api_key" . | wc -l

Search and exclude a directory (e.g. node_modules)

bash
grep -rn "password" . \ --include="*.js" \ --exclude-dir="node_modules" \ --exclude-dir=".git"

Always exclude node_modules and .git

Searching a project without excluding node_modules or .git will flood your results with thousands of irrelevant matches and run significantly slower. Add --exclude-dir=node_modules --exclude-dir=.git to every recursive grep on a project folder.

Get $200 Free →

View Hosting Plans →

Common Mistakes

Forgetting -r on a folder

Running grep "term" /var/log without -r will error with "Is a directory." You need grep -r "term" /var/log to search inside a folder recursively.

Special characters in your search term

Characters like ., *, [, and ( are regex special characters. If you're searching for them literally, either escape them with a backslash (\.) or use grep -F (fixed string mode) to treat the term as plain text, not a regex pattern.

Understanding the Commands

CommandWhat it does
grep "term" filePrints every line in file containing "term"
grep -r "term" dirRecursively searches all files in dir and subdirectories
grep -n "term" fileAdds line numbers to each matching line in output
grep -l "term" dirLists only filenames that contain a match — no line content
grep -c "term" fileCounts the number of matching lines in file
grep -v "term" filePrints every line that does NOT contain "term" (invert match)
--include="*.ext"Restricts search to files matching the glob pattern
--exclude-dir=nameSkips a directory entirely during recursive search

Frequently Asked Questions

How do I search for text inside files in Linux?

Use grep "search term" filename for a single file, or grep -rn "search term" /folder to search every file in a folder recursively. The -n flag adds line numbers so you can jump straight to each match.

How do I search multiple files with grep?

Use grep -r "term" /folder — the -r flag makes grep recurse into all subdirectories automatically. Add --include="*.py" to restrict results to a specific file type.

How do I make grep case insensitive?

Add the -i flag: grep -i "error" logfile.txt. This matches ERROR, error, Error, and any mixed-case variant.

How do I search for a word in a specific file type?

Use grep -rn "term" /folder --include="*.py". You can stack multiple --include flags to search several file types at once.

Try the Generator → Browse All Tools

BashSnippets logo

Written by Anguishe

Creator of BashSnippets.xyz

bashsnippets.xyz/about

Run this script on a real Linux server

Get $200 free credit — DigitalOcean

Get $200 Free →

Affiliate link · we earn a commission

Need a domain for your next project?

Register with Namecheap — free WHOIS privacy included

Check Domain Prices →

Affiliate link · we earn a commission

Related Snippets

Frequently Asked Questions

How do I run this script?

Save the grep examples as search.sh, chmod +x search.sh, then run ./search.sh or use the grep commands directly in your terminal.

Does this work on macOS?

Yes. grep is pre-installed on macOS. Use grep -r instead of grep -R on older macOS versions if needed.

How do I search for text inside files in Linux?

Use grep -rn "pattern" /path/to/dir to search recursively with line numbers. Add --include="*.ext" to filter by file type.

How do I make grep case insensitive?

Add the -i flag: grep -ri "pattern" /path/to/dir searches without case sensitivity.