powershellpowershell-5.1select-string

find string in file from last saved position - PowerShell


I wrote a simple PowerShell script, to find specific string in a given text file, using the Select-String cmdlet:

$SearchResult = $null

$FilePath = "c:\temp\app\events.log"

$FindString = "error"

$SearchResult = Select-String $FilePath -Pattern $FindString | Select -Last 1



if ($SearchResult -ne $null) {

    Write-Host "The file: ""$FilePath"", contains the string: '$FindString'."

} 
else {

    Write-Host "The file: ""$FilePath"", does not contain the string: '$FindString'."
}

While the above snippet is working, it will always return the string found in the file, even if new lines have been written to the target file.

I'm trying to find a way to save the last position/line the script read, and to start from that previous position/line, in the next iteration of the script.

While viewing the Select-String man page, I have found the -Skip switch, but it's been used with the number of lines to skip, and not the last position/line, to start from.

So, it seems that I need to create a text file, that will hold the last position/line of each iteration using Out-File, and to read from it using Get-Content in the start of the next iteration, but I'm s not sure how to find the last position/line in each iteration.

In Select-String, I can use:

$LineNumber = $SearchResult | Select -Expand LineNumber

To retrieve the number of the line, but it will work only if the string exists in the text file.

How can I find the last position/line in each iteration, and start from it, in the next iteration?


Solution

  • You could use something like this. It uses your Out-File idea and compares the line number you exported to the line number of the recent $SearchResult and if its greater do something and if not, do nothing.

    $SearchResult = $null
    
    $FilePath = "c:\temp\app\events.log"
    $LastLine = "c:\temp\app\LineNumber.txt"
    
    If([System.IO.File]::Exists($LastLine)){
    
        # The LineNumber.txt file exists.
        $StartLine = Get-Content -Path $LastLine
    }
    Else {
    
        # The file does not exist. Assign 0 to the $StartLine variable.
        $StartLine = "0"
    }
    
    $FindString = "error"
    
    $SearchResult = Select-String $FilePath -Pattern $FindString | Select -Last 1
    
    if ($SearchResult -ne $null) {
    
        $LineNumber = $SearchResult.LineNumber
    
        If($LineNumber -gt $StartLine) {
    
            # The line number is greatwer than the last occurrence.
            Write-Host "The file: ""$FilePath"", contains the string: '$FindString'."
    
            # Write write the new LineNumber to file.
            $LineNumber |  Out-File -FilePath c:\temp\app\LineNumber.txt
        }
        Else {
            
            # The line number is not greater.
            Write-Host "There was not a new occurrence of the pattern: $FindString."
        }
    
    } 
    else {
    
        Write-Host "The file: ""$FilePath"", does not contain the string: '$FindString'."
    }