hGrep.psm1
<#
.SYNOPSIS A grep-like tool with a color highlighting feature. .DESCRIPTION This function searches for text patterns in input strings. If input is an object, it is converted to a string prior to processing. Matched characters are highlighted. '(some command) | Select-MatchedString -Pattern <regex>' is similar to '(some command) | Output-String -Stream | Select-String -Pattern <regex> -AllMatch -CaseSensitive' with PowerShell 7.X, in which Select-String cmdlet has a highlighting feature. .PARAMETER Pattern Specifies the text patterns to find. Type a string or regular expression. If you type a string, use the SimpleMatch parameter. .PARAMETER BackgroundColor Specifies the background color for matches. (Alias: -bc) The default value is "Blue". .PARAMETER CapturegroupColor Specifies the foreground color for capture-group matches. (Alias: -cc) The default value is "Red". .PARAMETER ForegroundColor Specifies the foreground color for matches. (Alias: -fc) The default value is "White". .PARAMETER Group Specifies the name or number of capture group. (Alias: -g) The default value is "0". .PARAMETER ECMAScript Enables ECMAScript-compliant behavior. (Alias: -e) .PARAMETER IgnoreCase Makes matches case-insensitive. By default, matches are case-sensitive. (Alias: -i) .PARAMETER InputObject Specifies the text to be searched. (Alias: -io) .PARAMETER PassThru Outputs all lines, including ones that do not match. (Alias: -p) .PARAMETER Narrow Converts wide characters into narrow ones internally. (Alias: -n) Useful when you don't want to distinguish between narrow and wide characters. .PARAMETER SimpleMatch Uses a simple match rather than a regular expression match. (Alias: -s) .NOTES Author: earthdiver1 Version: V1.03 Licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. #> Function Select-MatchedString { [Alias('hGrep')] Param( [Parameter(Mandatory=$True)][String]$Pattern, [Alias("g")][String]$Group = "0", [Alias("e")][Switch]$ECMAScript, [Alias("i")][Switch]$IgnoreCase, [Alias("w")][Switch]$Narrow, [Alias("n")][Switch]$Number, [Alias("p")][Switch]$PassThru, [Alias("s")][Switch]$SimpleMatch, [Alias("bc")][ConsoleColor]$BackgroundColor = "Blue", [Alias("cc")][ConsoleColor]$CapturegroupColor = "Red", [Alias("fc")][ConsoleColor]$ForegroundColor = "White", [Parameter(ValueFromPipeline=$True)][Alias("io")][PSObject]$InputObject ) Begin { try { if ( -not $Pattern ) { break } if ( $Narrow ) { Add-Type -AssemblyName "Microsoft.VisualBasic" $Pattern = [Microsoft.VisualBasic.Strings]::StrConv($Pattern,[Microsoft.VisualBasic.VbStrConv]::Narrow) } if ( $SimpleMatch ) { $Pattern = [regex]::Escape( $Pattern ) } if ( $Number ) { $line = 0 $width = $host.UI.RawUI.BufferSize.Width - 7 } else { $width = $host.UI.RawUI.BufferSize.Width - 1 } $regexOptions = "Compiled" if ( $ECMAScript ) { $regexOptions += ", ECMAScript" } if ( $IgnoreCase ) { $regexOptions += ", IgnoreCase" } $Regex = New-Object Text.RegularExpressions.Regex $Pattern, $regexOptions $process_block = { Process { $line++ $i = 0 if ( $Narrow ) { $_ = [Microsoft.VisualBasic.Strings]::StrConv($_,[Microsoft.VisualBasic.VbStrConv]::Narrow) } $match = $Regex.Match($_,$i) $m = $match.Groups[$Group] if (-not $PassThru -and -not $m.Success) { return } if ( $Number ) { Write-Host $("{0,5}:" -F $line) -NoNewline } if ( $Group -eq "0" ) { while ($m.Success) { if ( $m.Index -ge $_.Length ) { break } if ( $m.Length -gt 0 ) { Write-Host $_.SubString($i, $m.Index - $i) -NoNewline Write-Host $m.Value -BackgroundColor $BackgroundColor -ForegroundColor $ForegroundColor -NoNewline $i = $m.Index + $m.Length } else { Write-Host $_.SubString($i, $m.Index - $i + 1) -NoNewline $i = $m.Index + 1 } $m = $Regex.Match($_,$i).Groups[0] } } else { while ( $m.Success ) { if ( $m.Index -ge $_.Length ) { break } $m0 = $match.Groups[0] if ( $m0.Length -gt 0 ) { Write-Host $_.SubString($i, $m0.Index - $i) -NoNewline Write-Host $_.SubString($m0.Index, $m.Index - $m0.Index) ` -BackgroundColor $BackgroundColor -ForegroundColor $ForegroundColor -NoNewline Write-Host $m.Value -BackgroundColor $BackgroundColor -ForegroundColor $CapturegroupColor -NoNewline $i = $m0.Index + $m0.Length $ii = $m.Index + $m.Length Write-Host $_.SubString($ii, $i - $ii) ` -BackgroundColor $BackgroundColor -ForegroundColor $ForegroundColor -NoNewline } else { Write-Host $_.SubString($i, $m0.Index - $i + 1) -NoNewline $i = $m0.Index + 1 } $match = $Regex.Match($_,$i) $m = $match.Groups[$Group] } } Write-Host $_.SubString($i) } } $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Out-String',[System.Management.Automation.CommandTypes]::Cmdlet) $wrappedCmdParameters = @{} if ( $PSBoundParameters.ContainsKey("InputObject") ) { $wrappedCmdParameters.Add("InputObject",$InputObject) } $wrappedCmdParameters.Add("Stream", $True) $wrappedCmdParameters.Add("Width", $width) $scriptCmd = {& $wrappedCmd @wrappedCmdParameters | & $process_block } $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin) $steppablePipeline.Begin($PSCmdlet) } catch { throw } } Process { try { $steppablePipeline.Process($_) } catch { throw } } End { try { $steppablePipeline.End() Remove-Variable Regex } catch { throw } } } Export-ModuleMember -Function Select-MatchedString -Alias hGrep |