How do you search for text and files in Linux using grep and find?
grep searches inside files for lines matching a pattern, for example grep -rn "error" logs/. find searches the directory tree for files by name, type, size or age, for example find . -name "*.log" -mtime -1. They are often combined to search text inside a chosen set of files.
Explain it simply
Think of a college library. find is like walking the shelves to locate books by their title, size or the date they arrived. grep is like opening books and scanning each page for a particular word.
So the simple rule is: find looks at file names and properties; grep looks at what is written inside files.
Example
grep: search inside files
grep "ERROR" app.log # lines containing ERROR
grep -i "error" app.log # ignore case
grep -n "ERROR" app.log # show line numbers
grep -c "ERROR" app.log # count matching lines
grep -v "DEBUG" app.log # lines that do NOT match
grep -rn "TODO" src/ # search a whole folder, recursively
grep -E "timeout|refused" app.log # extended regex: either word
grep -w "id" query.sql # match whole word only, not "valid"$ grep -n "ERROR" app.log
42:2026-10-02 10:14:03 ERROR Database connection refused
97:2026-10-02 10:20:51 ERROR Payment API timeoutfind: search for files
find . -name "*.log" # by name (quotes stop the shell expanding *)
find . -iname "readme*" # case-insensitive name
find /var/log -type f -size +100M # regular files bigger than 100 MB
find . -type d -name node_modules # directories only
find . -mtime -1 # modified in the last 24 hours
find /tmp -name "*.tmp" -mtime +7 -delete # delete temp files older than 7 daysUsing them together
find . -name "*.py" -exec grep -l "import requests" {} +This lists Python files that import requests. -exec ... {} + passes many file names to one grep call, which is faster than running grep once per file.
How it works
grep reads input line by line and prints each line that matches a regular expression. By default it uses basic regex; -E enables extended regex (|, +, ? without backslashes) and -F treats the pattern as plain text, which is faster and safer for strings with dots or brackets.
find walks the directory tree starting from the path you give it and checks each entry against your tests, from left to right. Tests are joined by "and" by default; you can use -o for "or" and ! for "not". Actions like -print (the default), -delete and -exec run on matches.
Real-world use
- Debugging production:
grep -i "exception" /var/log/app/*.log | tail -20. - Finding what is filling the disk:
find / -type f -size +1G 2>/dev/null. - Finding where a function is used in a codebase:
grep -rn "calculateTax" src/. - Cleaning old backups with
find -mtime +30 -deletein a cron job.
Common mistakes
- Not quoting patterns:
find . -name *.logmay be expanded by the shell before find sees it. - Forgetting that
.in grep means "any character".grep "1.2"also matches "1x2"; usegrep -F "1.2"for the literal text. - Putting
-deletebefore the tests, for examplefind . -delete -name "*.tmp", which deletes everything. Always run without-deletefirst to check the list.
What to say in the interview
"grep searches the contents of files for lines matching a pattern. I commonly use -i for case-insensitive, -n for line numbers, -r to search folders, -v to invert and -E for extended regex. find searches the file system by attributes like name, type, size and modification time, and can act on results with -exec or -delete. To search text inside specific files I combine them, for example find . -name '*.py' -exec grep -l 'requests' {} +."
Follow-up questions
- What is the difference between
-exec {} \;and-exec {} +? - How would you find and delete files older than 30 days?
- What does
xargsdo, and why usefind -print0 | xargs -0? - How is
locatedifferent fromfind?