Windows utility combining Linux grep functionality with anew-like merge capabilities
WinGrep is your essential command-line text search utility designed specifically for Windows environments. While Linux users enjoy powerful tools like grep and anew, Windows users often struggle with limited native text processing capabilities. WinGrep bridges this gap by combining the familiar grep functionality with anew-like merge capabilities, all optimized for Windows workflows.
Whether you're analyzing logs, processing bug bounty data, or filtering large text files, WinGrep provides pattern matching, regex support, and unique line collection in one lightweight executable. Simply search your patterns, collect unique results, and streamline your text processing tasks without juggling multiple tools or complex PowerShell syntax.
Win (Windows) + Grep (Global Regular Expression Print) = WinGrep
- Windows 7.0 or later
- No additional dependencies required
- Git clone this repo
git clone https://github.com/gigachad80/Wingrep
cd Wingrep
- Now build Go executable :
go build -o wingrep.exe
- Run Powershell ISE as administrator and Go to the direcctory where you have cloned the repo then run this command :
.\install-wingrep.ps1
-
Go to releases section and download the exe file as per your architecture.
-
Now , Run Powershell ISE as administrator and Go to the direcctory where you have cloned the repo then run this command .
.\install-wingrep.ps1
- β Linux grep compatibility - Works with pipes just like Linux grep
- β Case-sensitive and case-insensitive search
- β Line numbers support
- β Multiple file support
- β
Regex support (extended regex with
-E) - β Invert matching (show non-matching lines)
- β Stdin support - Reads from stdin when no files specified
- β Windows native - Works in Command Prompt and PowerShell
- β Anew-like merge mode - Append unique lines to files
| Feature | Linux grep | anew | wingrep |
|---|---|---|---|
| Pattern matching | β | β | β |
| Case insensitive | β | β | β |
| Line numbers | β | β | β |
| Regex support | β | β | β |
| Unique line dedup | β | β | β |
| Append to file | β | β | β |
| Windows native | β | β | β |
| Stdin support | β | β | β |
| Option | Description |
|---|---|
-i |
Ignore case |
-n |
Show line numbers |
-v |
Invert match (show non-matching lines) |
-E |
Use extended regex |
-m <file> |
Merge mode: append unique matching lines to file (anew-like) |
-q |
Quiet mode: don't print to stdout when using merge mode |
-d |
Dry run: show what would be added without writing to file |
-h |
Show help |
# Search for "error" in a file
wingrep "error" logfile.txt
# Search ignoring case
wingrep -i "ERROR" logfile.txt
# Show line numbers
wingrep -n "function" code.js
# Use with pipe (like Linux)
type file.txt | wingrep "pattern"
cat file.txt | wingrep "pattern"
# Multiple files
wingrep "TODO" *.js *.go *.py
# Invert match (show lines that DON'T contain pattern)
wingrep -v "comment" code.js
# Use regex patterns
wingrep -E "^[0-9]+" numbers.txt# Instead of Linux: cat file.txt | grep "pattern"
# Use: type file.txt | wingrep "pattern" ( CMD.exe )
# Or: cat file.txt | wingrep "pattern" (if you have cat via Git Bash)
# Find errors in log files
wingrep -i "error" *.log
# Find function definitions in code
wingrep -n "function\|def\|func" *.js *.py *.go
# Find IP addresses (regex)
wingrep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" access.log
# Search in piped output
dir | wingrep ".txt"
netstat -an | wingrep ":80"The -m flag enables anew-like functionality, allowing you to append unique matching lines to a file while avoiding duplicates.
# Basic merge - append unique matching lines to output.txt
cat input.txt | wingrep -m output.txt "pattern" ( Powershell )
# Collect unique error messages from multiple log files
wingrep -i -m unique-errors.txt "error" *.log
# Quiet mode - don't print to stdout, just append to file
wingrep -m domains.txt -q "\.com" urls.txt
# Dry run - see what would be added without writing
wingrep -m results.txt -d "TODO" *.go
# Combine with other flags
wingrep -i -n -m matches.txt "function" *.js- Deduplication: Only lines that don't already exist in the target file are appended
- Stdout output: New unique lines are printed to stdout (unless
-qis used) - File creation: Target file is created if it doesn't exist
- Preserves order: Lines are appended in the order they're found
# Collect unique failed login attempts
wingrep -i -m failed-logins.txt "failed.*login" *.log
# Find unique suspicious IPs
wingrep -E "blocked.*[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" -m suspicious-ips.txt security.log# Collect all TODO items across project
wingrep -i -m todos.txt "todo\|fixme\|hack" *.js *.py *.go
# Find unique API endpoints
wingrep -E "GET|POST|PUT|DELETE.*/" -m endpoints.txt *.log
# Gather unique error patterns
wingrep -E "Exception|Error.*:" -m errors.txt *.log# Collect unique error codes from web server logs
wingrep -E "HTTP [4-5][0-9][0-9]" -m http-errors.txt access.log
# Find unique database errors
wingrep -i -m db-errors.txt "database.*error\|connection.*failed" *.log
# Gather unique user agents
wingrep -E "User-Agent: .*" -m user-agents.txt access.log
| Task | PowerShell π€‘ | WinGrep πΏ | Winner |
|---|---|---|---|
| Basic Pattern Search | Select-String "pattern" file.txt |
wingrep "pattern" file.txt |
πΏ Shorter syntax |
| Case Insensitive Search | Select-String -Pattern "pattern" -CaseSensitive:$false file.txt |
wingrep -i "pattern" file.txt |
πΏ Much simpler |
| Show Line Numbers | Select-String "pattern" file.txt | Select-Object LineNumber,Line |
wingrep -n "pattern" file.txt |
πΏ One flag vs pipeline |
| Invert Match | Get-Content file.txt | Where-Object {$_ -notmatch "pattern"} |
wingrep -v "pattern" file.txt |
πΏ Direct flag |
| Regex Search | Select-String -Pattern "^[0-9]+" file.txt |
wingrep -E "^[0-9]+" file.txt |
πΏ Simpler flag |
| Multiple Files | Select-String "pattern" *.txt | Format-Table |
wingrep "pattern" *.txt |
πΏ Native support |
| Operation | PowerShell π€‘ | WinGrep πΏ | Complexity |
|---|---|---|---|
| Search + Get Unique Lines | Select-String "ERROR" *.log | Select-Object -Property Line -Unique | Out-File unique.txt |
wingrep -m unique.txt "ERROR" *.log |
PS: 3 cmdlets vs WG: 1 flag |
| Case Insensitive + Line Numbers + Multiple Files | Select-String -Pattern "error" -CaseSensitive:$false *.log | Select-Object Filename,LineNumber,Line |
wingrep -i -n "error" *.log |
PS: Complex pipeline vs WG: 2 flags |
| Regex + Invert + Unique Collection | Get-Content *.txt | Where-Object {$_ -notmatch "^#"} | Sort-Object -Unique | Out-File result.txt |
wingrep -E -v -m result.txt "^#" *.txt |
PS: 4 cmdlets vs WG: 3 flags |
| Dry Run Preview | $results = Get-Content file.txt | Where-Object {...}; Write-Host "Would add $($results.Count) lines" |
wingrep -d -m output.txt "pattern" file.txt |
PS: Custom scripting vs WG: Built-in flag |
Task: Find all ERROR lines from multiple log files, get unique ones, save to file
| PowerShell π€‘ | WinGrep πΏ |
|---|---|
$errors = Select-String "ERROR" *.log<br>$unique = $errors | Select-Object -Property Line -Unique<br>$unique | Out-File -FilePath errors.txt |
bash<br>wingrep -m errors.txt "ERROR" *.log<br> |
| 3 lines, 3 variables | 1 line, done |
Task: Extract unique URLs containing "api" from multiple files, case insensitive
| PowerShell π€‘ | WinGrep πΏ |
|---|---|
$urls = Select-String -Pattern "api" -CaseSensitive:$false *.txt<br>$unique_urls = $urls | Select-Object -Property Line -Unique<br>$unique_urls | Out-File -FilePath api_urls.txt -Append<br> |
bash<br>wingrep -i -m api_urls.txt "api" *.txt<br> |
| 3 commands, pipeline hell | 1 command, clean |
Task: Find lines NOT starting with #, show line numbers, case insensitive
| PowerShell π€‘ | WinGrep πΏ |
|---|---|
Get-Content config.txt | <br> ForEach-Object -Begin {$i=0} -Process {<br> $i++; if($_ -notmatch "^#") {<br> Write-Output "$i`:$_"<br> }<br> }<br> |
bash<br>wingrep -v -n "^#" config.txt<br> |
| Complex loop + logic | 2 flags, simple |
| Aspect | PowerShell π€‘ | WinGrep πΏ |
|---|---|---|
| Startup Time | ~2-3 seconds (PowerShell initialization) | ~50ms (native binary) |
| Memory Usage | ~50-100MB (PowerShell runtime) | ~3MB (Go binary) |
| Large Files | Can crash with Out-of-Memory | Streams data efficiently |
| Pipeline Overhead | Each | creates new process |
Single process handles all |
| PowerShell Problems π€‘ | WinGrep Solutions πΏ |
|---|---|
Verbose syntax: Select-String -Pattern "x" -CaseSensitive:$false |
Concise: wingrep -i "x" |
Pipeline complexity: cmd1 | cmd2 | cmd3 |
Single command with flags |
| No built-in unique merge | Native -m flag (anew-like) |
| Memory hungry for large files | Efficient streaming |
| Slow startup due to .NET initialization | Instant startup (native binary) |
| Complex object manipulation required | Direct text processing |
| No dry-run capabilities | Built-in -d flag |
| Escaping hell with special characters | Simple pattern matching |
- PowerShell:
Select-String -Pattern "ERROR" -CaseSensitive:$false *.log | Select-Object -Property Line -Unique | Out-File errors.txt - WinGrep:
wingrep -i -m errors.txt "ERROR" *.log
- Native Go binary vs PowerShell's .NET overhead
- Single process vs multiple pipeline processes
- Memory efficient streaming vs object-heavy processing
- Built-in unique line collection (like
anew) - Dry-run capabilities
- Simple flag-based interface
- Cross-architecture support (amd64, arm64, 386)
- Familiar grep syntax for Unix users
- No PowerShell knowledge required
- Portable single executable
- Consistent behavior across Windows versions
PowerShell π€‘: "Let me writeπ€βοΈ a complex pipeline with multiple cmdlets, object manipulation, and pray it doesn't run out of memory..."
WinGrep πΏ: "One command, few flags, job done. Next!"
WinGrep makes you feel like a text processing ninja π₯·, while PowerShell makes you feel like you're debugging someone else's spaghetti code π
| Command | Description |
|---|---|
wingrep "pattern" |
Basic search |
wingrep -i "pattern" |
Case-insensitive |
wingrep -n "pattern" |
Show line numbers |
wingrep -v "pattern" |
Invert match |
wingrep -E "pattern" |
Use regex |
wingrep -m file "pattern" |
Merge unique matches to file |
wingrep -i -n "pattern" |
Case-insensitive + line numbers |
wingrep -v -n "pattern" |
Invert + line numbers |
wingrep -E -i "pattern" |
Regex + case-insensitive |
wingrep -m file -q "pattern" |
Merge quietly (no stdout) |
wingrep -m file -d "pattern" |
Dry run merge |
# Find files containing pattern
dir /b *.txt | wingrep "sample"
# Find running processes
tasklist | wingrep -i "chrome"
# Find network connections
netstat -an | wingrep ":80"
# Merge unique results from multiple commands
tasklist | wingrep -m processes.txt "chrome"
netstat -an | wingrep -m connections.txt ":80"# Collect unique URLs from multiple files
wingrep -E "https?://[^\s]+" -m all-urls.txt *.html *.txt
# Gather unique error codes
wingrep -E "HTTP [4-5][0-9][0-9]" -m error-codes.txt access.log
# Collect unique IP addresses
wingrep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" -m ips.txt *.log
# Find unique function names across codebase
wingrep -E "function\s+\w+" -m functions.txt *.jssample.txt
Error: Database connection failed
INFO: Application started successfully
Warning: Low disk space detected
ERROR: Authentication failed for user john
Debug: Processing request #12345
Info: User login successful
error: File not found
code.js
function calculateTotal() {
console.log("Starting calculation");
return total;
}
// TODO: Add error handling
var result = calculateTotal();
function processData() {
// Handle data processing
}# Case-insensitive search with line numbers
C:\> type sample.txt | wingrep -i -n "error" ( CMD.exe )
1:Error: Database connection failed
4:ERROR: Authentication failed for user john
7:error: File not found
# Find functions in code files
C:\> wingrep -n "function" code.js
1:function calculateTotal() {
7:function processData() {
# Invert match - show non-error lines
C:\> type sample.txt | wingrep -v -i "error" ( CMD.exe )
INFO: Application started successfully
Warning: Low disk space detected
Debug: Processing request #12345
Info: User login successful
# Regex: find lines starting with numbers
C:\> type log.txt | wingrep -E "^[0-9]" ( CMD.exe )
2024-01-15 10:30:25 [INFO] Server started
2024-01-15 10:31:12 [ERROR] Database timeout
# Merge mode: collect unique errors
C:\> wingrep -i -m errors.txt "error" *.log
ERROR: Database timeout
ERROR: Failed to save data
(these lines are also appended to errors.txt)- Use merge mode for collecting unique data across multiple files
- Combine flags for powerful filtering:
-i -n -m results.txt - Use dry run mode (
-d) to preview what would be added - Quiet mode (
-q) is perfect for silent data collection - Regex mode (
-E) enables powerful pattern matching - Remember: You can wingrep with
catif you're running using Powershell and usetypeif you're using CMD.
I created WinGrep to have a single, convenient tool for text processing without PowerShell's verbose cmdlets or complex terminal setups. Instead of remembering Select-String -Pattern "error" -CaseSensitive:$false *.log | Select-Object -Property Line -Unique | Out-File results.txt for simple pattern matching, I wanted familiar grep-style commands like wingrep -i -m results.txt "error" *.log that just work.
I don't want to write bloated PS commands, and as an avid Linux user, I prefer simple grep-like syntax. I know WSL exists, and terminal emulators like Tabby (which I personally use) work great, but why change shells when you can simply open PS or CMD and run the command?
**Total Time taken to develop, test and writing README : Approx 3 hr - 3 hr 30 min
- @tomnomnom for creating anew for inspiration
π§ Email: pookielinuxuser@tutamail.com
Licensed under GNU Affero General Public License 3.0
Need help? Run wingrep -h for quick reference or check the examples above! or contact at mail or raise issuse
π Last Updated: June 17, 2025