Home > Back-end >  Powershell - Capture and display PREVIOUS line when string match = true
Powershell - Capture and display PREVIOUS line when string match = true

Time:09-02

I have a script that captures and displays the line of a string match. Very simple. What I need now is the previous line to be displayed. I may need the previous few lines but for now my task is to just capture and display the previous line once a string match is found.

Here is my current script. I have no clue how to alter it for my purposes. Any help is appreciated.

$searchWords="NEW", "CATLG", "DELETE"


# List the starting(parrent) Directory here - the script will search thropugh every file and every sub-directory - starting fromn the one listed below  
Get-Childitem -Path "C:\src\" -Include "*.job"  -Recurse | 
  Select-String -Pattern $searchWords | 

# the output will contain the [Found] word, the document it found it in and the line contents/line number containing the word
    Select Filename,Line,@{n='SearchWord';e={$_.Pattern}}, LineNumber

CodePudding user response:

Get-Childitem -Path "C:\src" -Include "*.job"  -Recurse | 
  Select-String -Context 1 -Pattern $searchWords | 
  Select-Object Filename,
                @{n='LineBefore';e={$_.Context.PreContext[0]}},
                @{n='SearchWord';e={$_.Pattern}},
                LineNumber

Note:

  • -Context accepts two arguments: the first one specifies how many lines to capture before, and the second for how many to capture after; e.g., -Context 1, 2 captures one line before, and 2 lines after each match, reflected as arrays of strings in .Context.PreContext and .Context.PostContext, respectively.

  • -Context only works meaningfully with line-by-line input:

    • When you specify files for Select-String to search through:

      • Either: By providing [System.IO.FileInfo] instances such as via Get-ChildItem, as in your case.
      • Or: By using Select-String's own -Path or -LiteralPath parameter (which doesn't support recursion, however)
    • When you provide individual lines as input, such as via an array (stream) of lines (as opposed to a multi-line string).

      • Note that while Get-Content (without using -Raw) does provide a stream of lines, it is much faster to use Get-ChildItem to pipe a [System.IO.FileInfo] instance describing that file instead.
  • Related