4

I have a script that searches for a series of strings (stored in a txt file) in the contents of files in a directory. I would like to modify it to also list the text around the string found (these are regular strings, not regex expressions). I played around a lot and it seems like I need to use -Context, but I am not sure how to get the text from that.

Also, the files I am searching may not have linefeeds, so if it could just get the xx characters before and after the search term, that would be better.

Here's what I have so far (I omitted the looping though files parts):

$result = Get-Content $file.FullName | Select-String $control -quiet  
If ($result -eq $True) 
{ 
  $match = $file.FullName 
  "Match on string :  $control  in file :  $match" | Out-File $output -Append 
  Write-host "Match on string :  $control  in file :  $match"
} 

If it could write the context, that would be perfect. Seems like I need to use $_Matches, but not sure how.

2 Answers 2

1

If $control is just a regular string, can you turn it into a regular expression?

$n  = 3
$re = "(.{0,$n})(" + [Regex]::Escape($control) + ")(.{0,$n})"

$result = (Get-Content $file.FullName) -match $re

With this, the $matches hashtable should give you access to the $n characters before and after the match:

if ($result.Length -gt 0) {
  echo "Before: $($matches[1])"
  echo "After:  $($matches[3])"
}
Sign up to request clarification or add additional context in comments.

5 Comments

You can also modify the check to if ($result) which (in my eyes) reads nicer. But maybe I golf too much in PowerShell ;)
That would make $result look like a boolean value, which it isn't. I prefer to avoid this kind of confusion, even if the language allows it.
Ah, fair enough. In PowerShell < 3 you might get an error then when the file only contains a single matching line :-). (Granted, when using just $result you'd get problems with a single matching line too, if it's an empty string, but that's unlikely given the scenario.)
I get a lot of "the variable '$matches' cannot be retrieved because it has not been set."
I also think if the characters right before or after were a line feed, it wouldn't find a match. I think using [\s\S] might get around that.
0

Here is what I have now and it seems to work:

  $regex = "[\s\S]{0,$ContextChars}$SearchTerm[\s\S]{0,$ContextChars}"
  $results = Get-Content $file.FullName | Select-String -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }      

  if ($results)
  {
    foreach($result in $results)
    {
      $display = $result
      "File: $file   Match ---$display---"  
    }
  }  

The only thing I wish I had but don't know how to get it is the line number the match is found on.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.