PoshCode Archive  Artifact [65950706a1]

Artifact 65950706a1f6161ca55346b3a48377afc94f96a924af4d38e894503349445e1d:

  • File Find-String.ps1 — part of check-in [93fd2b540a] at 2018-06-10 13:38:40 on branch trunk — Find-String and Highligh-Matches work together to do formatted output of matches in strings (user: unknown size: 4214)

# encoding: ascii
# api: powershell
# title: Find-String
# description: Find-String and Highligh-Matches work together to do formatted output of matches in strings
# version: 1.0
# type: script
# license: CC0
# function: Find-String
# x-poshcode-id: 426
# x-archived: 2010-06-30T08:37:53
#
#
## Find-String.ps1
########################################################################################################################
## Find-String is basically a PowerShell 1.0 wrapper around { select-string } which will append the "Matches" to it
## Highlight-Matches takes a collections of MatchInfo objects and prints them out, highlighting the actual match.
## 
## Based on:
## http://weblogs.asp.net/whaggard/archive/2007/03/23/powershell-script-to-find-strings-and-highlight-them-in-the-output.aspx
##
## It should be noted that this DOES NOT return objects on the pipeline unless you specify -passthru
## If you do specify passthru, it will Add the "Matches" property to the MatchInfo objects, 
## making them more like ## the 2.0 MatchInfo object.
########################################################################################################################
function Find-String {
PARAM( [regex] $pattern = $(Read-Host "Regular expression search pattern")
     , [string] $filter = "*.*"
	  , [switch] $recurse
	  , [switch] $caseSensitive
     , [switch] $summary
)

$v2 = [bool](new-object Microsoft.PowerShell.Commands.MatchInfo | gm "Matches")

if ($pattern.ToString() -eq "") { throw "Nothing to search for! Please provide a search pattern!" }

if( (-not $caseSensitive) -and (-not $pattern.Options -match "IgnoreCase") ) {
	$pattern = New-Object regex $pattern.ToString(),@($pattern.Options,"IgnoreCase")
}

if($summary) {
   [string[]] $summaryText = ""
   $summaryText += "Matches  Lines  FileName"
   $summaryText += "-------  -----  --------"

   $totalCount = 0; $totalLines = 0;
}
# Do the actual find in the files
Get-ChildItem -recurse:$recurse -filter:$filter |
   foreach { 
      if($summary) {
         $fileCount = 0; $lineCount = 0;
      }
      if($v2) {
         $select = "Select-String -input `$_ -caseSensitive:`$caseSensitive -pattern:`$pattern -AllMatches"
      } else {
         $select = "Select-String -input `$_ -caseSensitive:`$caseSensitive -pattern:`$pattern"
      } 
      
      iex $select | foreach {
         if(!$v2) {
            Add-Member -Input $_ -MemberType NoteProperty -Name "Matches" -Value $pattern.Matches($_.Line) -ErrorAction SilentlyContinue
         }

         Write-Output $_
         
         if($summary) {
   		   $lineCount++
   		   $fileCount += $_.Matches.Count
         }
	   }
      if($summary) {
         $totalCount += $fileCount;
         $totalLines += $lineCount;
         if( $fileCount -gt 0) {
            $summaryText += "{0,7}  {1,5}  {2}" -f $fileCount, $lineCount, $_
         }
      }
   }
if($summary) {
   $summaryText += "-------  -----  -----"
   $summaryText += "{0,7}  {1,5}  TOTALS" -f $totalCount, $totalLines
   $summaryText += ""
   $summaryText | Out-Host
}

}

# Write the line with the pattern highlighted in red
function Highlight-Matches
{
   PARAM ([Microsoft.PowerShell.Commands.MatchInfo[]]$match, [Switch]$Passthru)
   BEGIN {
      if($match) { 
         $match | Write-Host-HighlightMatches
      }
   }
   PROCESS { 
      if($_ -and ($_ -isnot [Microsoft.PowerShell.Commands.MatchInfo])) {
         throw "Expected Microsoft.PowerShell.Commands.MatchInfo objects on the pipeline"
      } elseif($_) {
         Write-Host ("{0} {1,5} {2,3}: " -f $_.FileName, "($($_.LineNumber))", $_.matches.Count) -nonewline
         $index = 0;
         foreach($match in $_.Matches) {
            Write-Host $_.line.SubString($index, $match.Index - $index) -nonewline
            Write-Host $match.Value -ForegroundColor Red -nonewline
            $index = $match.Index + $match.Length
         }
         if($index -lt $_.line.Length) {
            Write-Host $_.line.SubString($index) -nonewline
         }
         Write-Host
         
         if($Passthru) { $_ }
      }
   }
}