Skip to content

Searching inside files on Linux#

These are two different questions, answered by two different commands: "where is a file with this name" is not the same as "which file contains this text." find answers the first, grep -r the second - and most of the time you need both together.

The shortcut

If you have connected VeriTeknik MCP to your AI assistant (Claude, ChatGPT, Cursor...), just ask:

"Find the files under /var/www that contain 'TypeError'"

Your assistant runs the search on the server and brings back the matching lines with file name and line number. The connection needs the Server investigation group for this. The search is limited to web, log, application and service configuration directories (/var/www, /var/log, /srv, /opt, /home, /etc/nginx and the like) and skips known credential files such as .env files and private keys; other configuration files, such as wp-config.php, can still be searched.

Search by filename: find#

find /var/www -name "*.log"

Finds every file under /var/www, including subdirectories, whose name ends in .log. For case-insensitive matching, use -iname:

find /var/www -iname "*.PHP"

The find filters you will actually use#

find /home -type f -name "*.conf"        # files only, not directories
find /home -type d -name "cache"          # only directories named "cache"
find /var/log -type f -mtime -7           # files modified in the last 7 days
find /var/log -type f -size +100M         # files larger than 100MB
find / -user www-data 2>/dev/null         # files owned by www-data

-mtime -7 means "newer than 7 days", -mtime +7 means "older than 7 days" - the plus/minus sign is easy to read backwards, so double-check it.

Doing something with what find finds: -exec

find /var/log -name "*.log" -mtime +30 -exec rm {} \;

Deletes every .log file older than 30 days. {} is replaced with each matched file, \; marks the end of the command. Before an irreversible operation like -exec rm, run with -print first to see what you are about to delete.

Search by file content: grep -r#

grep -r "ERROR" /var/log/nginx/

Scans every file under a directory, including subdirectories, and prints lines that contain "ERROR". Useful additions:

grep -rn "ERROR" /var/log/nginx/          # with line numbers
grep -rl "ERROR" /var/log/nginx/          # just the matching filenames, not the lines
grep -ri "error" /var/log/nginx/          # case-insensitive
grep -r --include="*.log" "ERROR" /var/log/   # only search .log files
grep -r --exclude-dir=node_modules "TODO" .   # skip this directory entirely

-l (lowercase L) is particularly handy: it answers "which files contain this text" as a list, so you are not scrolling through thousands of lines of grep -r output.

Combining both: find + grep#

If you need to search within a specific file type and --include is not flexible enough:

find . -name "*.php" -exec grep -l "eval(" {} \;

Finds .php files that contain eval( - a classic pattern for hunting down suspicious or malicious code.

The faster option: ripgrep (rg)#

In a large directory tree - especially with folders like node_modules or .git - grep -r slows down noticeably. ripgrep automatically skips what .gitignore excludes and scans in parallel, and is usually several times faster:

sudo apt install -y ripgrep    # Ubuntu/Debian
sudo dnf install -y ripgrep    # Rocky/AlmaLinux
rg "ERROR" /var/log/nginx/

The syntax is close to grep; the biggest differences are that it respects .gitignore/.ignore automatically and is recursive by default.

With Morpheus

"list every .log file under /var/log that changed in the last 24 hours"

"find lines containing 'connection refused' in the nginx logs"

Morpheus runs both of these in one request - you do not have to write find and grep separately.

Checklist#

  • [ ] Used find for a filename, grep -r for file content
  • [ ] Tried ripgrep if speed was an issue in a large tree (node_modules, .git)
  • [ ] Previewed with -print before an irreversible -exec rm