Reputation: 65
How can I read only the last two rows of a .log file? The following script reads the full .log file which returns an incorrect status. For my particular case the string returning the correct status per .log file is written in the last two rows.
function Get-Status($file) {
if (Select-String -Quiet 'Finished with errors' $_.FullName) {
return "ERROR"
} elseif (Select-String -Quiet 'Finished with warnings' $_.FullName) {
return "WARNING"
} elseif (Select-String -Quiet 'Finished.' $_.FullName) {
return "SUCCESS"
} else {
return "FAILED"
}
}
Get-ChildItem C:\logfolder\*.log | % {
[PSCustomObject] @{
Name = $_.Name;
Date = $_.LastWriteTime;
Status = Get-Status($_.FullName)]
}
}
Upvotes: 1
Views: 1634
Reputation: 153
Unix tail equivalent command in Windows Powershell
At the stop of your Get-Status() function, include this:
$lines = Get-Content $file | Select-Object -Last 2
The do your search against $lines instead.
Upvotes: 1
Reputation: 61028
Another variation is to use a switch
in the Get-Status
function:
function Get-Status([string]$file) {
# get the last two lines of the log and recombine them with a newline
switch -Regex ((Get-Content -Path $file -Tail 2) -join "`r`n") {
'(?m)^Finished with error' { 'ERROR' ; break}
'(?m)^Finished with warning' { 'WARNING' ; break}
'(?m)^Finished' { 'SUCCESS' ; break}
default { 'FAILED'}
}
}
Get-ChildItem -Path 'C:\logfolder' -Filter '*.log' -File | ForEach-Object {
[PSCustomObject] @{
Name = $_.Name
Date = $_.LastWriteTime
Status = Get-Status $_.FullName
}
}
Please notice that with PowerShell you should use a space character betweet the function name and the parameter, not put this parameter inside brackets.
Upvotes: 0
Reputation: 176
In recent versions of PowerShell Get-Content supports -Tail parameter, so you can pipe Get-Content into select string, e.g. for first if statement:
Get-Content -Tail 2 $_.FullName | Select-String -Quiet 'Finished.'
Upvotes: 0
Reputation: 1999
you can read the files content using Get-Content
and the select only the last two lines like:
$fileContent = Get-Content -Path $file -Tail 2
so adding this to your Get-Status
function should return the correct state:
function Get-Status($file) {
$fileContent = Get-Content -Path $file -Tail 2
if (Select-String -Quiet -Pattern 'Finished with errors' -InputObject $fileContent) {
return "ERROR"
} elseif (Select-String -Quiet -Pattern 'Finished with warnings' -InputObject $fileContent) {
return "WARNING"
} elseif (Select-String -Quiet -Pattern 'Finished.' -InputObject $fileContent) {
return "SUCCESS"
} else {
return "FAILED"
}
}
Upvotes: 2