03 of 10 — Terminal Mastery
A practical guide to finding files, searching text, reading content, and filtering results on Windows, macOS, and Linux.
Imagine you're working on a large React application.
Your project contains hundreds of components, thousands of lines of code, configuration files, and documentation.
You remember using a function called getUserData, but you can't remember which file contains it.
What do you do?
Open every file individually?
Search through folders manually?
There is a much better solution.
You use your terminal.
The command line provides powerful tools for finding files, searching their contents, reading logs, and filtering large amounts of information.
In this article, we'll explore these tools across Windows PowerShell, macOS, and Linux.
By the end, you'll know how to:
- Find files by name and extension.
- Search for specific text inside files.
- Read files directly from the terminal.
- Inspect large log files efficiently.
- Display only the lines you need.
- Combine search operations.
- Search through real development projects.
Let's get started.
1. Finding Files and Directories
The first skill we'll learn is finding files by their names.
Imagine you have this project:
my-project/ ├── src/ │ ├── components/ │ │ ├── Header.jsx │ │ └── Footer.jsx │ ├── utils/ │ │ └── helpers.js │ └── App.jsx ├── public/ │ └── logo.svg ├── package.json └── README.md You want to locate helpers.js, but you don't remember its exact directory.
Let's solve that.
Linux and macOS: The find Command
The find command searches for files and directories within a specified location.
Basic syntax:
find [path] [expression] To search for a file named helpers.js:
find . -name "helpers.js" Let's understand this command:
-
findstarts the search. -
.means the current directory. -
-namespecifies the filename pattern. -
"helpers.js"is the name we're searching for.
Possible output:
./src/utils/helpers.js Find All JavaScript Files
find . -name "*.js" This searches recursively for files ending in .js.
To find both .js and .jsx files:
find . -type f \( -name "*.js" -o -name "*.jsx" \) Here:
-
-type frestricts results to regular files. -
-omeans OR. -
\(and\)group expressions.
Find Only Directories
find . -type d Find Files with a Specific Extension
find . -type f -name "*.json" This is especially useful when working with configuration-heavy projects.
2. Finding Files in Windows PowerShell
PowerShell provides its own filesystem search capabilities.
The most useful starting point is Get-ChildItem.
Search for a Specific Filename
Get-ChildItem -Path . -Filter "helpers.js" -Recurse Let's break it down:
-
Get-ChildItemretrieves filesystem items. -
-Path .starts in the current directory. -
-Filterspecifies the filename. -
-Recursesearches through subdirectories.
Find All JavaScript Files
Get-ChildItem -Path . -Filter "*.js" -Recurse -File The -File option ensures that only files are returned.
Find All React Components
Get-ChildItem -Path . -Include "*.jsx", "*.tsx" -Recurse -File This is useful when exploring React or TypeScript projects.
Find Directories Only
Get-ChildItem -Path . -Directory -Recurse Search by Filename Using Wildcards
Get-ChildItem -Path . -Recurse -File | Where-Object { $_.Name -like "*config*" } This finds files whose names contain config.
For example:
vite.config.js tsconfig.json config.ts PowerShell's Where-Object allows you to filter objects based on conditions.
We'll explore pipelines more deeply in Article 04.
3. Finding Files in Windows Command Prompt
Command Prompt also supports recursive file searches.
Use:
where /r . helpers.js This searches recursively from the current directory.
To find all JavaScript files:
where /r . *.js The where command can search for matching files in directory trees.
Don't confuse it with PowerShell's Where-Object.
They are different commands with different purposes.
4. Reading Files from the Terminal
Finding a file is only half the job.
Now you need to inspect its contents.
Let's explore the most common ways to read files.
Linux and macOS: The cat Command
cat displays file contents directly in the terminal.
cat README.md Example output:
# My Project This is a React application. ## Installation npm install You can also display multiple files:
cat file1.txt file2.txt This prints their contents one after another.
Important: cat is useful for short files, but it can become inconvenient when reading very large files.
That's where other commands come in.
Windows PowerShell: Get-Content
PowerShell provides:
Get-Content README.md You can also use its alias:
gc README.md For reading a file line by line:
Get-Content README.md PowerShell returns the file's contents as objects representing lines of text.
Windows CMD: type
Command Prompt uses:
type README.md This displays the contents of the specified file.
5. Reading Large Files Efficiently
Imagine you're inspecting a server log containing 50,000 lines.
Displaying the entire file isn't always practical.
Instead, you can inspect only the beginning or end.
The head Command
On Linux and macOS:
head logfile.txt By default, this displays the first 10 lines.
To display the first 20 lines:
head -n 20 logfile.txt The tail Command
To display the last 10 lines:
tail logfile.txt To display the last 20 lines:
tail -n 20 logfile.txt Follow a Log File in Real Time
One of the most useful terminal tricks is:
tail -f application.log This continuously displays new lines as they are added to the file.
It's especially useful when monitoring application logs or debugging a running server.
Press Ctrl + C to stop following the file.
PowerShell Alternatives
Display the first 10 lines:
Get-Content application.log -TotalCount 10 Display the last 10 lines:
Get-Content application.log -Tail 10 Follow a log file as it changes:
Get-Content application.log -Wait This is the PowerShell equivalent of a common tail -f workflow.
What About CMD?
CMD doesn't provide direct equivalents of head and tail as built-in commands.
You can use:
more application.log This lets you view content page by page.
For more advanced inspection, PowerShell is usually the better option on Windows.
6. Searching for Text Inside Files
Now we reach one of the most powerful terminal skills.
Suppose you want to find every occurrence of:
getUserData inside your source code.
Instead of opening every file, you can search recursively.
Linux and macOS: The grep Command
grep searches text using patterns.
Basic syntax:
grep "search-term" filename Example:
grep "getUserData" app.js This displays matching lines from app.js.
Search Recursively
grep -R "getUserData" ./src The -R option searches through directories recursively.
Display Line Numbers
grep -Rn "getUserData" ./src The -n option includes line numbers.
Example output:
./src/services/user.js:15:const getUserData = () => {}; ./src/components/Profile.jsx:8:import { getUserData } from "../services/user"; Now you know exactly where the function appears.
Case-Insensitive Search
grep -Ri "getuserdata" ./src The -i option ignores letter case.
Search Only Specific File Types
grep -Rn --include="*.js" "getUserData" ./src This restricts the search to JavaScript files.
You can also search multiple extensions:
grep -Rn --include="*.js" --include="*.jsx" "getUserData" ./src 7. Searching Text in Windows PowerShell
PowerShell provides a powerful command called Select-String.
It's similar to grep, but it works with PowerShell's object-based pipeline.
Search Inside a File
Select-String -Path "app.js" -Pattern "getUserData" Search Recursively
Get-ChildItem -Path .\src -Recurse -File | Select-String -Pattern "getUserData" This searches every file under src.
Include Line Numbers
PowerShell's Select-String includes line information in its results.
Example:
src\services\user.js:15:const getUserData = () => {}; Case-Insensitive Search
By default, Select-String searches case-insensitively.
You can explicitly use:
Select-String -Path "app.js" -Pattern "getuserdata" -CaseSensitive Search Only JavaScript Files
Get-ChildItem -Path .\src -Filter "*.js" -Recurse -File | Select-String -Pattern "getUserData" You can also search JSX files:
Get-ChildItem -Path .\src -Include "*.js", "*.jsx" -Recurse -File | Select-String -Pattern "getUserData" 8. Searching Text in Windows CMD
Command Prompt provides the findstr command.
It can search for text inside files.
Search Inside a File
findstr "getUserData" app.js Search Recursively
findstr /S "getUserData" src\*.js The /S option searches through subdirectories.
Include Line Numbers
findstr /N "getUserData" app.js Case-Insensitive Search
findstr /I "getuserdata" app.js Search Multiple Files
findstr "React" *.js findstr is useful for simple text searches, although its pattern-matching behavior differs from grep and PowerShell's Select-String.
9. Reading Specific Lines from a File
Sometimes you don't need an entire file.
You only need a particular section.
For example, imagine a configuration file contains 500 lines, and you want to inspect lines 20 through 30.
Linux and macOS
Combine sed with a line range:
sed -n '20,30p' config.txt Here's what the options mean:
-
-ndisables automatic printing. -
20,30specifies the line range. -
pprints the selected lines.
You can also use:
sed -n '20p' config.txt This displays only line 20.
PowerShell
Use Get-Content with Select-Object:
Get-Content config.txt | Select-Object -Skip 19 -First 11 Why skip 19?
Because PowerShell's -Skip counts from zero, while humans usually count lines starting from one.
This displays lines 20 through 30.
CMD
You can combine more with line-number skipping:
more +19 config.txt This starts displaying the file from approximately the twentieth line.
For precise line-range selection, PowerShell or another dedicated text-processing tool is preferable.
10. Counting Lines, Words, and Characters
Sometimes you want to understand the size of a file without opening it.
Linux and macOS provide the wc command.
Count Lines
wc -l app.js Count Words
wc -w README.md Count Bytes
wc -c app.js Count Characters
wc -m app.js These commands are especially useful when analyzing logs, documentation, or large source files.
PowerShell
Count lines:
(Get-Content app.js).Count Count characters:
(Get-Content app.js -Raw).Length The -Raw parameter reads the file as one string instead of returning individual lines.
CMD
You can count lines using:
find /C /V "" app.js This is a common CMD technique for counting non-empty strings, though blank-line handling can make it less suitable as an exact general-purpose line counter.
For reliable text analysis on Windows, PowerShell offers more flexibility.
11. Combining Search Operations
Now let's combine what we've learned.
Imagine you have a React project and want to find every occurrence of useState inside JavaScript and JSX files.
Linux / macOS
grep -Rn \ --include="*.js" \ --include="*.jsx" \ "useState" ./src This searches recursively and displays line numbers.
PowerShell
Get-ChildItem .\src -Recurse -File | Where-Object { $_.Extension -in ".js", ".jsx" } | Select-String -Pattern "useState" This performs the same general task using PowerShell objects and pipelines.
CMD
findstr /S /N "useState" src\*.js src\*.jsx Now imagine searching for a function across an entire project containing hundreds of files.
A few commands can save you a lot of manual work.
Developer tip: In real projects, you may eventually want a faster search tool called ripgrep (rg). We'll introduce modern developer tools in Article 08.
12. A Real-World Debugging Exercise
Let's apply these skills to a realistic situation.
Imagine your Node.js application writes errors to a file called server.log.
You want to find every line containing the word ERROR.
Linux / macOS
grep -in "ERROR" server.log This searches without considering letter case and displays line numbers.
PowerShell
Select-String -Path server.log -Pattern "ERROR" CMD
findstr /I /N "ERROR" server.log Now suppose you only want the latest 20 lines of the log.
Linux / macOS:
tail -n 20 server.log PowerShell:
Get-Content server.log -Tail 20 And if you want to monitor new log entries:
Linux / macOS:
tail -f server.log PowerShell:
Get-Content server.log -Wait This is a common debugging workflow when working with backend applications.
13. Common Mistakes to Avoid
Here are some mistakes beginners frequently make.
1. Searching the wrong directory
Always verify your current location before starting a search.
pwd Or in PowerShell:
Get-Location 2. Forgetting recursive search
A search inside the current directory doesn't necessarily include all nested directories unless you request recursion.
3. Confusing find and grep
On Unix-like systems:
-
findlocates filesystem entries. -
grepsearches text inside files.
They solve different problems.
4. Printing enormous files
Avoid displaying thousands of lines when you only need a small section.
Use head, tail, less, or PowerShell's Select-Object.
5. Searching generated directories unnecessarily
JavaScript projects often contain directories such as:
node_modules/ dist/ build/ Searching these directories can produce enormous amounts of irrelevant output.
Exclude them when appropriate.
For example:
grep -Rn \ --exclude-dir=node_modules \ --exclude-dir=dist \ "useState" . 6. Assuming every search tool uses the same syntax
grep, findstr, and Select-String have different options and pattern-matching rules.
Learn the tool you're actually using.
14. Practice Challenges
Time to put your knowledge to work.
Create a directory named search-lab and add these files:
search-lab/ ├── app.js ├── helpers.js ├── README.md ├── config.json └── logs/ └── server.log Put the following content in app.js:
function getUserData() { return { name: "Alex" }; } function getProducts() { return []; } console.log(getUserData()); Put this in helpers.js:
function formatName(name) { return name.trim(); } function calculateTotal(items) { return items.length; } Put this in server.log:
INFO Server started INFO Database connected ERROR Database connection timeout INFO Retrying connection ERROR Authentication failed INFO Server stopped Now complete these challenges.
Challenge 1: Find Files
Find all .js files inside search-lab.
Challenge 2: Search for a Function
Find every occurrence of getUserData and display the line numbers.
Challenge 3: Search for Errors
Find every line containing ERROR inside server.log.
Challenge 4: Inspect a File
Display the first two lines of server.log.
Challenge 5: Count Lines
Count the number of lines in helpers.js.
Challenge 6: Find Configuration Files
Find every .json file inside your project.
Challenge 7: Combine Your Skills
Search the entire project for the word function, but exclude any generated or dependency directories if they exist.
Try solving every challenge using your operating system's native shell.
Quick Command Reference
| Task | Linux / macOS | PowerShell | CMD |
|---|---|---|---|
| Find files | find | Get-ChildItem | where /r |
| Read file | cat | Get-Content | type |
| First lines | head | Select-Object -First | more |
| Last lines | tail | Get-Content -Tail | more |
| Follow logs | tail -f | Get-Content -Wait | — |
| Search text | grep | Select-String | findstr |
| Count lines | wc -l | .Count | find /C /V "" |
| Show line ranges | sed | Select-Object | more +N |
Remember that these are functional equivalents for common tasks, not identical implementations.
What's Next?
You can now locate files, search through source code, inspect logs, and extract useful information without manually opening every file.
But something even more powerful is waiting.
So far, we've mostly executed individual commands.
What happens when you want to combine several commands into one workflow?
For example:
- Find all JavaScript files.
- Search them for a specific function.
- Filter the results.
- Save the output into a separate file.
This is where Pipes, Redirection, and Command Chaining come in.
In Article 04, we'll explore how commands communicate with each other and how to build powerful workflows from simple operations.
Next Article: Pipes, Redirection and Command Chaining
Final Thoughts
Searching through files is one of those skills that seems simple until you start working on large projects.
Once you become comfortable with find, grep, Select-String, and the other tools covered here, you'll spend much less time searching manually.
The terminal isn't just a place to execute commands.
It's a powerful environment for exploring, inspecting, and understanding your entire codebase.
Learn to search efficiently, and you'll spend more time building and less time looking for things.
Happy coding!
