How can I find files, and text inside files, on Linux?
What this is
The two halves of searching a server: find locates files by their properties (name, size, age), grep locates text inside them. Between them, every "where is..." question on a VPS has an answer, and half the recipes in this knowledge base are one of these two wearing context.
find: locating files
The shape is always find <where> <tests> <action>:
find /var/www -name "*.conf" # by name (quote the pattern!)
find /var/www -iname "*.JPG" # case-insensitive
find / -xdev -size +500M # bigger than 500 MB
find /var/www -mtime -2 # modified in the last 2 days
find /var/log -type f -name "*.gz" # files only (-type d for dirs)
The tests combine (-name "*.log" -size +100M -mtime +30: old fat logs), and two recipes from elsewhere in these docs show the range: recently changed files after a compromise (-mtime -14), and deleting a million tiny files (-type f -delete, where rm chokes).
The superpower is -exec, run a command on every match:
find /var/www -name "*.bak" -exec ls -lh {} \; # inspect first...
find /var/www -name "*.bak" -delete # ...then act
(That order, inspect with ls before any delete, is the safety habit, always.)
grep: locating text inside files
grep -r "database_password" /var/www # recursive through a tree
grep -ri "error" /var/log/nginx/error.log # case-insensitive
grep -rn "listen" /etc/nginx/ # -n: show line numbers
grep -rl "wp_debug" /var/www # -l: just list matching files
-r is the flag that turns grep from a filter into a search engine. Useful companions: -v inverts (lines not matching), -A3/-B3 show lines after/before a match (context around an error), and zgrep searches rotated .gz logs without unpacking them.
The combined classic, find picks the files, grep reads them:
find /var/www -name "*.php" -exec grep -l "base64_decode" {} +
(that particular one being a web-shell hunt).
The modern upgrades: fd and ripgrep
Both worth installing on a box you work on daily: fd (apt install fd-find, command fdfind) is find with sane defaults, fdfind config just works, and ripgrep (apt install ripgrep, command rg) is a dramatically faster recursive grep that skips .git and binaries by default, rg "database_password" /var/www. Same concepts, less typing; the classic tools remain worth knowing because they're on every machine you'll ever touch.
(locate exists too, instant name lookups from a nightly index, but on a server its index is stale by definition; find tells the truth right now.)
Still need help?
You can open a support ticket. So we can help on the first reply, it's worth mentioning:
- the VPS hostname or IP,
- what you're searching for, and the command you tried.
Related questions
- "How do I find a file by name on Linux?"
- "How do I search for text in all files in a directory?"
- "How do I find files modified recently, or over a certain size?"
- "What are fd and ripgrep and should I use them?"