You have mastered creating and manipulating files. But what happens when you cannot find what you are looking for? You know you wrote that function last week, but which file was it in? You need to find all files modified yesterday, or search for every occurrence of a specific error message across thousands of log files. The terminalWhat is terminal?A text-based interface where you type commands to interact with your computer. Also called the command line or shell. gives you tools to find needles in haystacks.
Finding files by name: find
The find command searches through directories recursively, checking each file against your criteria.
find . -name "readme.txt" # Exact name in current dir and below
find . -name "*.js" # All JavaScript files
find . -name "*test*" # Anything containing "test"
find . -iname "readme.txt" # Case-insensitive searchFiltering by type and time
find . -type f -name "*.txt" # Files only
find . -type d -name "node_modules" # Directories only
find . -type f -mtime -1 # Modified less than 1 day ago
find . -type f -mmin -60 # Modified less than 60 minutes ago
find . -type f -size +1M # Larger than 1 MB| Option | What it does | Example |
|---|---|---|
-name "pattern" | Match exact name | -name "file.txt" |
-iname "pattern" | Case-insensitive match | -iname "README*" |
-type f | Find files only | -type f -name "*.js" |
-type d | Find directories only | -type d -name "build" |
-mtime n | Modified n days ago | -mtime -1 (within last day) |
-size +n | Larger than n | -size +1M (over 1 MB) |
-exec cmd {} \; | Run command on each match | -exec rm {} \; |
Executing commands on found files
You can run a command on every file that matches:
find . -name "*.log" -exec rm {} \; # Delete all .log files
find . -name "*.js" -exec cp {} backup/ \; # Copy all JS files to backupfind commands with multiple nested flags that are hard to read and easy to get wrong. For example, AI might suggest find . -type f -name "*.js" -not -path "*/node_modules/*" -newer reference.txt -exec grep -l "import" {} + when a simple grep -r "import" src/ would give you the answer. Always ask yourself: is there a simpler way?Searching inside files: grep
grep searches inside files for text patterns. Where find locates files by name, grep locates files by content.
grep "TODO" notes.txt # Search one file
grep "function" *.js # Search all JS files
grep -r "TODO" src/ # Search recursively in directory
grep -rn "error" src/ # Recursive with line numbersUseful grep flags
| Flag | What it does | Example |
|---|---|---|
-i | Case-insensitive | grep -i "error" file |
-r | Recursive (subdirectories) | grep -r "text" folder/ |
-n | Show line numbers | grep -n "text" file |
-v | Invert (lines without match) | grep -v "debug" file |
-c | Count matches only | grep -c "error" file |
-l | List filenames only | grep -l "text" *.txt |
-C 3 | Show 3 lines of context | grep -C 3 "error" file |
Piping: combining commands
The pipe symbol (|) chains commands together, sending the output of one command as input to the next. Think of it like an assembly line.
find . -name "*.js" | grep "test" # Find JS files containing "test" in path
grep -r "error" logs/ | head -20 # First 20 error matches
grep -r "TODO" src/ | wc -l # Count all TODO comments
find . -name "*.js" | grep -v "node_modules" | grep "component"That last example finds all .js files, excludes anything in node_modules, and shows only those with "component" in the path.
Modern alternatives
The classic tools are everywhere, but modern alternatives are faster and friendlier.
| Tool | Use when | Key advantage |
|---|---|---|
find | You need maximum compatibility | Every Unix system has it |
grep | Simple text searching | Every Unix system has it |
fd | You want ease of use | Respects .gitignore, simpler syntax |
rg (ripgrep) | You search code frequently | Multi-core, respects .gitignore |
# fd: simpler find
fd "*.js" # No flags needed
fd -e js # Find by extension
# ripgrep: faster grep
rg "TODO" # Recursive by default
rg "function" --type js # Search only JS filesLearn the classics first, they are on every server you will ever access. Then enhance your workflow with modern tools on your development machine.
Quick reference
| Task | Command | Notes |
|---|---|---|
| Find by name | find . -name "file.txt" | Use * for wildcards |
| Find files only | find . -type f | -type d for directories |
| Search in files | grep "text" file.txt | -r for recursive |
| Case-insensitive | grep -i "text" file | Matches "Text", "TEXT", etc. |
| Show line numbers | grep -n "text" file | Useful for locating issues |
| Count matches | grep -c "text" file | Returns number only |
| Chain commands | cmd1 \| cmd2 | Pipe output to next command |
| First N results | grep "text" file \| head -N | Limit output |