Advertisement

The Script

Paste this into search.sh. Change SEARCH_DIR, KEYWORD, and the --include file type to match what you're looking for.

search.sh
#!/bin/bash
# Search Files for Text (grep)
# Searches all .txt files in a folder for a keyword.
# Shows filename and line number for each match.
#
# USAGE: ./search.sh
# REQUIRES: bash, grep (pre-installed on all Linux/macOS)

SEARCH_DIR="$HOME/documents"   # ← folder to search inside
KEYWORD="TODO"                # ← word or phrase to find
FILE_TYPE="*.txt"             # ← file extension to search

echo "Searching for '$KEYWORD' in $SEARCH_DIR..."
echo "---"

grep -rn "$KEYWORD" "$SEARCH_DIR" --include="$FILE_TYPE"

echo "---"
echo "✓ Done."
✓ What this does, line by line

grep -rn searches recursively through all subfolders (-r) and includes line numbers in results (-n). "$KEYWORD" is the word or phrase to find. "$SEARCH_DIR" is the folder to search inside. --include="$FILE_TYPE" limits the search to files matching that pattern — without it, grep searches every file including binaries.

Step-by-Step Setup

Step 1 — Create the file

terminal
nano search.sh

Paste the script, then Ctrl+X → Y → Enter to save.

Step 2 — Set your variables

VariableExampleWhat it means
SEARCH_DIR$HOME/documentsThe folder (and all subfolders) to search inside
SEARCH_DIR/var/www/htmlA web project directory
KEYWORDTODOFinds every line containing the word TODO
KEYWORDapi_keyHunts for hardcoded secrets across your project
FILE_TYPE*.txtSearch only plain text files
FILE_TYPE*.pySearch only Python files
FILE_TYPE*.shSearch only bash scripts
FILE_TYPE*.jsSearch only JavaScript files

Step 3 — Make it executable and run

terminal
chmod +x search.sh
./search.sh
✓ Sample output

Searching for 'TODO' in /home/user/documents...
---
/home/user/documents/notes.txt:14: TODO: fix the login bug
/home/user/documents/project.txt:3: TODO: add error handling
---
✓ Done.

Advertisement

Variations

Run it as a one-liner without a script

For quick one-off searches you don't need a script at all. Just run directly in the terminal:

terminal
# Search all .sh files for the word "error"
grep -rn "error" ~/scripts --include="*.sh"

# Search ALL file types (no filter)
grep -rn "TODO" ~/myproject

Case-insensitive search

Add -i to match regardless of capitalisation — finds TODO, todo, Todo all at once:

search-nocase.sh
#!/bin/bash
SEARCH_DIR="$HOME/documents"
KEYWORD="todo"

grep -rni "$KEYWORD" "$SEARCH_DIR" --include="*.txt"

Show only filenames, not the matching lines

Add -l to get just a list of files that contain the keyword — useful when you have many matches:

search-files-only.sh
#!/bin/bash
SEARCH_DIR="$HOME/documents"
KEYWORD="TODO"

# -l = show only filenames, not the matching lines
grep -rl "$KEYWORD" "$SEARCH_DIR" --include="*.txt"

Count how many matches are in each file

search-count.sh
#!/bin/bash
SEARCH_DIR="$HOME/myproject"
KEYWORD="TODO"

# -c = count of matches per file
grep -rc "$KEYWORD" "$SEARCH_DIR" --include="*.py" \
  | grep -v ":0"   # hide files with zero matches

Search for multiple keywords at once

search-multi.sh
#!/bin/bash
SEARCH_DIR="$HOME/myproject"

# -e lets you pass multiple patterns
grep -rn -e "TODO" -e "FIXME" -e "HACK" "$SEARCH_DIR" \
  --include="*.py"

Search and save results to a file

search-save.sh
#!/bin/bash
SEARCH_DIR="$HOME/myproject"
KEYWORD="TODO"
OUTPUT="$HOME/todo-list.txt"

grep -rn "$KEYWORD" "$SEARCH_DIR" --include="*.py" > "$OUTPUT"
echo "✓ Results saved to $OUTPUT"
Search across your entire cloud server in seconds DigitalOcean droplets give you a full Linux environment to script against — from $4/month. New accounts get $200 free credit.
Get $200 Free → DigitalOcean Referral Badge

Common Mistakes

⚠ Forgetting --include and searching binary files

Without --include, grep searches every file including compiled binaries and image files. This produces garbage output and slows things down. Always specify a file type unless you intentionally want to search everything.

⚠ Special characters in your keyword

If your keyword contains characters like ., *, [, or (, grep treats them as regex. To search for them literally, add -F (fixed string mode): grep -rn -F "error()" ~/project

⚠ Too many results with no context

If grep returns hundreds of matches, add -l to see just the filenames first, then open the specific file. Or use -m 5 to limit output to the first 5 matches per file.

Advertisement

grep Flag Cheat Sheet

FlagWhat it doesExample
-rSearch recursively through subfoldersgrep -r "word" ~/folder
-nShow line number with each matchgrep -n "word" file.txt
-iCase-insensitive matchinggrep -ri "word" ~/folder
-lShow filenames only, not the matching linesgrep -rl "word" ~/folder
-cCount matches per filegrep -rc "word" ~/folder
-vInvert — show lines that do NOT matchgrep -v "word" file.txt
-FTreat keyword as plain string, not regexgrep -rF "error()" ~/folder
-m 5Stop after 5 matches per filegrep -rn -m 5 "word" ~/folder
--includeLimit to files matching a patterngrep -rn "word" ~/folder --include="*.py"
--excludeSkip files matching a patterngrep -rn "word" ~/folder --exclude="*.log"

Frequently Asked Questions

How do I search all files in a folder for a word in Linux?

Use grep -rn 'keyword' /path/to/folder to search recursively. Add --include='*.txt' to limit the search to specific file types. The -n flag shows the line number alongside each match.

What does grep -rn do?

-r makes grep search recursively through all subfolders. -n includes the line number in every result. Together they give you: filename, line number, and the matching line — everything you need to find and act on a match fast.

How do I search only specific file types with grep?

Add the --include flag: grep -rn 'keyword' /folder --include='*.py' searches only Python files. Use *.sh for shell scripts, *.js for JavaScript, and so on.

How do I make grep case insensitive?

Add -i: grep -rni 'keyword' /folder matches any capitalisation of the keyword. Useful when you're not sure how a term appears across different files.

Related Snippets