DEV Community

Cover image for PowerShell Select-String: Find Text in Files Fast
arnostorg
arnostorg

Posted on

PowerShell Select-String: Find Text in Files Fast

The PowerShell Select-String cmdlet finds text inside files — the same job grep does on Linux/macOS and findstr does in classic CMD. When you are hunting for an error code in logs, checking whether a config key exists, or scanning a repo for a TODO, it is faster than opening every file by hand.

For the official reference, see Microsoft Learn’s Select-String.

Want to practice PowerShell in a live browser terminal (no install)? Try the free interactive lessons on CMD Master — PowerShell and command-line training.

What does Select-String do?

Select-String -Path .\notes.txt -Pattern "TODO"
Enter fullscreen mode Exit fullscreen mode

That prints every line in notes.txt that contains TODO, plus the file name and line number. Matches are case-insensitive by default on Windows PowerShell 5.1; add -CaseSensitive when case matters.

Search one file or many

Point -Path at a single file, a wildcard, or a list:

Select-String -Path .\app.log -Pattern "ERROR"
Select-String -Path .\*.log -Pattern "timeout"
Select-String -Path .\config.json,.\settings.json -Pattern "apiKey"
Enter fullscreen mode Exit fullscreen mode

Preview what you will search with Get-ChildItem first when the wildcard is broad:

Get-ChildItem .\*.log
Select-String -Path .\*.log -Pattern "Exception"
Enter fullscreen mode Exit fullscreen mode

Recurse into folders: -Recurse

To walk a directory tree, combine a path with -Recurse (or pipe files in):

Select-String -Path .\logs\*.log -Pattern "FATAL" -Recurse
Enter fullscreen mode Exit fullscreen mode

Or pipe from Get-ChildItem for tighter filters:

Get-ChildItem .\src -Filter *.ps1 -Recurse |
  Select-String -Pattern "Write-Host"
Enter fullscreen mode Exit fullscreen mode

Piping is often clearer when you want to exclude folders, filter by extension, or skip huge binary files.

Patterns: simple text and regex

-Pattern accepts a string or a regular expression:

# literal-ish search (still regex — escape special characters)
Select-String -Path .\readme.md -Pattern "C:\\Windows"

# regex: lines that look like IPv4 addresses
Select-String -Path .\access.log -Pattern '\d{1,3}(\.\d{1,3}){3}'
Enter fullscreen mode Exit fullscreen mode

To treat the pattern as plain text (no regex), use -SimpleMatch:

Select-String -Path .\notes.txt -Pattern "C:\temp\file[1].txt" -SimpleMatch
Enter fullscreen mode Exit fullscreen mode

Show surrounding lines: -Context

-Context shows lines before and after each match — perfect for log forensics:

# 2 lines before, 3 lines after
Select-String -Path .\app.log -Pattern "NullReference" -Context 2,3
Enter fullscreen mode Exit fullscreen mode

You can also pass a single number for the same count on both sides: -Context 2.

List only matching files

Sometimes you care which files contain a string, not every hit:

Select-String -Path .\*.config -Pattern "ConnectionString" -List
Enter fullscreen mode Exit fullscreen mode

-List stops after the first match in each file, which is faster on large trees.

Case, invert, and quiet checks

# case-sensitive
Select-String -Path .\code.ps1 -Pattern "Error" -CaseSensitive

# lines that do NOT match
Select-String -Path .\hosts.txt -Pattern "^#" -NotMatch
Enter fullscreen mode Exit fullscreen mode

In scripts, test whether anything matched with the boolean result of a capture:

$hits = Select-String -Path .\app.log -Pattern "FATAL" -Quiet
if ($hits) {
  Write-Host "Found FATAL entries — investigate."
}
Enter fullscreen mode Exit fullscreen mode

-Quiet returns $true / $false instead of match objects.

Select-String vs findstr vs Get-Content

Tool Best for
Select-String PowerShell pipelines, regex, recursion, rich match objects
findstr Quick CMD one-liners without loading PowerShell
Get-Content + Where-Object When you already have content in memory and need custom filters

Prefer Select-String when you are already in PowerShell. Prefer findstr only for tiny CMD scripts that must stay .bat-only.

Safe habits

  1. Narrow the path before a recursive search — start with Get-ChildItem, then pipe.
  2. Prefer -SimpleMatch when the pattern includes brackets, dots, or backslashes you did not mean as regex.
  3. Use -Context on production logs so you see the failure, not just the keyword.
  4. Avoid searching huge binary folders (node_modules, .git) unless you filter them out.

Practice it live

Open a free PowerShell lesson on CMD Master’s interactive CLI platform and try Select-String in a real terminal in your browser — no VM, no install.

Quick cheat sheet

Select-String -Path .\file.txt -Pattern "text"
Select-String -Path .\*.log -Pattern "ERROR" -Recurse
Select-String -Path .\app.log -Pattern "FAIL" -Context 2,2
Select-String -Path .\*.ps1 -Pattern "TODO" -List
Select-String -Path .\data.csv -Pattern "id,name" -SimpleMatch
Enter fullscreen mode Exit fullscreen mode

Once this clicks, pair it with Get-ChildItem for discovery and Get-Content when you need the full file after a hit. That trio covers most day-to-day text hunting on Windows.

Top comments (0)