Lesson 9: Search & Find
Goal: Master finding files, directories, and text patterns anywhere on your system.
Table of Contents
- find — Search by Attributes
- locate — Fast Indexed Search
- grep — Search Inside Files
- Combining find and grep
- 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 — Fast Indexed Search
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.
Basic search
# 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
Recursive search
# 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
Exercise 3: Combined search
# 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 filesgrep -rn— recursive with line numbers (most common combo)grep -v— invert match (exclude lines)find ... -exec grep ... {} \;— combine for powerful searches2>/dev/null— suppress permission errors
Next Lesson: Lesson 10: Text Processing →