Lesson 9: Search & Find

Goal: Master finding files, directories, and text patterns anywhere on your system.


Table of Contents

  1. find — Search by Attributes
  2. locate — Fast Indexed Search
  3. grep — Search Inside Files
  4. Combining find and grep
  5. Exercises

find — Search by Attributes

find searches the filesystem in real time based on file attributes.

Basic syntax

find [where] [criteria] [action]

Search by name

# Find files named "config.yaml"
find /etc -name "config.yaml"

# Case-insensitive search
find /home -iname "readme.md"

# Find all .log files
find /var/log -name "*.log"

# Find all .jpg and .png files
find ~/Pictures -name "*.jpg" -o -name "*.png"

Search by type

# Files only
find /home -type f -name "*.txt"

# Directories only
find /home -type d -name "config"

# Symbolic links only
find /usr -type l
Type Meaning
f Regular file
d Directory
l Symbolic link
b Block device
c Character device

Search by size

# Files larger than 100 MB
find / -type f -size +100M

# Files smaller than 1 KB
find . -type f -size -1k

# Files exactly 10 MB
find . -type f -size 10M

# Files between 10 MB and 100 MB
find . -type f -size +10M -size -100M

Size units: c (bytes), k (KB), M (MB), G (GB)

Search by time

# Modified in the last 7 days
find . -type f -mtime -7

# Modified more than 30 days ago
find . -type f -mtime +30

# Accessed in the last 24 hours
find . -type f -atime -1

# Changed in the last 60 minutes
find . -type f -mmin -60

# NOT modified in the last 365 days (old files)
find /home -type f -mtime +365

Search by permissions

# Files with permission 777
find . -type f -perm 777

# Files writable by others
find . -type f -perm -o+w

# Files owned by root
find / -type f -user root -name "*.conf" 2>/dev/null

# SUID files (potential security concern)
find / -type f -perm -4000 2>/dev/null

Search by owner

# Files owned by a user
find /home -user benjamin

# Files owned by a group
find /var -group www-data

# Files with no owner (orphaned)
find / -nouser 2>/dev/null

Actions on found files

# Delete found files
find /tmp -type f -name "*.tmp" -delete

# Execute a command on each file
find . -type f -name "*.log" -exec rm {} \;

# Execute with confirmation
find . -type f -name "*.bak" -ok rm {} \;

# Print with details
find . -type f -name "*.sh" -exec ls -lh {} \;

# Change permissions on found files
find . -type f -name "*.sh" -exec chmod 755 {} \;

Practical examples

# Find the 10 largest files on the system
find / -type f -exec du -h {} + 2>/dev/null | sort -rh | head -10

# Find empty files
find . -type f -empty

# Find empty directories
find . -type d -empty

# Find files modified today
find . -type f -mtime 0

# Find and count all Python files
find . -type f -name "*.py" | wc -l

locate searches a pre-built database, making it extremely fast.

Install and update

# Install
sudo apt install mlocate

# Update the database
sudo updatedb

Basic usage

# Find files by name
locate nginx.conf

# Case-insensitive
locate -i readme.md

# Count matches
locate -c "*.py"

# Limit results
locate -l 10 "*.conf"

find vs locate

Feature find locate
Speed Slow (real-time search) Very fast (database)
Freshness Always current May be outdated
Criteria Name, size, date, perm... Name only
Needs root For some paths No

Use locate for quick lookups, find when you need up-to-date results or advanced criteria.


grep — Search Inside Files

grep (Global Regular Expression Print) searches for text patterns inside files.

# Search for "error" in a file
grep "error" /var/log/syslog

# Case-insensitive
grep -i "error" /var/log/syslog

# Show line numbers
grep -n "error" /var/log/syslog

# Count matches
grep -c "error" /var/log/syslog
# Search in all files in a directory
grep -r "TODO" ~/project/

# With line numbers
grep -rn "TODO" ~/project/

# Only show filenames (not the matching lines)
grep -rl "TODO" ~/project/

# Exclude directories
grep -rn "TODO" ~/project/ --exclude-dir=node_modules

Invert match

# Show lines that do NOT contain "error"
grep -v "error" logfile.txt

# Show non-comment lines in a config file
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"

Context — lines before and after

# Show 3 lines after each match
grep -A 3 "error" logfile.txt

# Show 2 lines before each match
grep -B 2 "error" logfile.txt

# Show 2 lines before and after
grep -C 2 "error" logfile.txt

Regular expressions

# Lines starting with "Error"
grep "^Error" logfile.txt

# Lines ending with "failed"
grep "failed$" logfile.txt

# Match "color" or "colour"
grep "colou\?r" file.txt

# Match IP addresses (simple)
grep -E "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" logfile.txt

# Match email-like patterns
grep -E "[a-zA-Z0-9.]+@[a-zA-Z0-9.]+" file.txt

# Extended regex with -E (or use egrep)
grep -E "(error|warning|critical)" logfile.txt

Colorized output

# Always show colors
grep --color=always "pattern" file.txt

# Make it the default (add to .bashrc)
alias grep='grep --color=auto'

Practical examples

# Find which config files mention a port
grep -rn "8080" /etc/

# Find all functions in a Python file
grep -n "def " script.py

# Count how many times a word appears
grep -c "error" /var/log/syslog

# Find all TODO/FIXME comments in a project
grep -rn "TODO\|FIXME" ~/project/

# Show active (non-comment) SSH config
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"

# Search compressed log files
zgrep "error" /var/log/syslog.2.gz

Combining find and grep

The real power comes from combining these tools.

# Find all .py files containing "import os"
find . -name "*.py" -exec grep -l "import os" {} \;

# Find large log files with errors
find /var/log -name "*.log" -size +1M -exec grep -l "ERROR" {} \;

# Find config files modified recently containing a keyword
find /etc -name "*.conf" -mtime -7 -exec grep -n "listen" {} +

# Find and replace text in multiple files
find . -name "*.txt" -exec sed -i 's/old/new/g' {} \;

Exercises

Exercise 1: find practice

# 1. Find all .conf files in /etc
find /etc -name "*.conf" 2>/dev/null | head -20

# 2. Find files larger than 50 MB on the system
find / -type f -size +50M 2>/dev/null | head -10

# 3. Find empty directories in your home
find ~ -type d -empty

# 4. Find files modified in the last hour
find ~ -type f -mmin -60

# 5. Find all shell scripts (*.sh) and list them
find / -type f -name "*.sh" -exec ls -lh {} \; 2>/dev/null | head -10

Exercise 2: grep practice

# 1. Find your user in /etc/passwd
grep "$USER" /etc/passwd

# 2. Count how many users have /bin/bash as shell
grep -c "/bin/bash" /etc/passwd

# 3. Show all lines with "error" in syslog (case-insensitive)
grep -i "error" /var/log/syslog 2>/dev/null | tail -5

# 4. Find all installed packages containing "python"
dpkg -l | grep -i python | head -10
# 1. Create test data
mkdir -p /tmp/search-test
echo "This has an error" > /tmp/search-test/log1.txt
echo "All good here" > /tmp/search-test/log2.txt
echo "Another error found" > /tmp/search-test/log3.txt

# 2. Find files containing "error"
grep -rl "error" /tmp/search-test/

# 3. Use find + grep together
find /tmp/search-test -name "*.txt" -exec grep -l "error" {} \;

# 4. Clean up
rm -rf /tmp/search-test

Key Takeaways

  • find — search by name, size, date, permissions (real-time, flexible)
  • locate — instant search by name (database, may be stale)
  • grep — search text patterns inside files
  • grep -rn — recursive with line numbers (most common combo)
  • grep -v — invert match (exclude lines)
  • find ... -exec grep ... {} \; — combine for powerful searches
  • 2>/dev/null — suppress permission errors

Next Lesson: Lesson 10: Text Processing →