How to Get the Last Line of a File
Have you ever needed to read just the last line of a file (i.e. “the last row”) in Powershell? It’s easier than I thought. If you ask for the last several rows (as shown in the commented-out code in the example below, you will get back an array of rows. If you get just the last row, you will get it in a string variable.
$myFileName = "c:\Users\neal.walters\Documents\test.csv" #Example of how to get the last 3 rows #$LastThreeRowsArray = (Get-Content $myFileName)[-1 .. -3] # Get last one row of file into variable $lastDataRow = (Get-Content $myFileName)[-1] #parse the CSV data back into separate variables, one for each column $dataArray = $lastDataRow.Split(",") $lastRowDate = [DateTime] $dataArray[0] #convert back to DateTime datatype $lastRowStatus = $dataArray[1] $lastRowAction = $dataArray[2] $lastRowKeyword = $dataArray[3] Write-Host "`$lastDataRow=$lastDataRow" Write-Host "Date=$lastRowDate" Write-Host "Status=$lastRowStatus" Write-Host "Action=$lastRowAction" Write-Host "Keyword=$lastRowKeyword" $currentDateTime = get-date $dateTimeDiff = $currentDateTime - $lastRowDate $minutesDiff = $dateTimeDiff.Minutes $totalMinutesDiff = $dateTimeDiff.TotalMinutes Write-Host "`$currentDateTime =$currentDateTime" Write-Host "`$dateTimeDiff=$dateTimeDiff" Write-Host "`$minutesDiff=$minutesDiff " Write-Host "`$totalMinutesDiff=$totalMinutesDiff " $maxAcceptableLapseMinutes = 15 if ($totalMinutesDiff -gt $maxAcceptableLapseMinutes) { Write-Host "No video created for more than $maxAcceptableLapseMinutes minutes!" # do so logic here to handle that issue }
Test Data File:
1/5/2015 8:51,Success,CreatedVideo,best appliances in Abilene TX 1/5/2015 8:51,Success,CreatedVideo,best appliances in Irving TX 1/5/2015 8:51,Failure,CreatedVideo,best appliances in Farmers Branch TX 1/5/2015 8:52,Success,CreatedVideo,best appliances in Abilene TX 1/5/2015 8:52,Success,CreatedVideo,best appliances in Boston MA 1/5/2015 8:52,Success,CreatedVideo,best appliances in West Newton MA 1/5/2015 8:52,Success,CreatedVideo,best appliances in Boca Raton FL
Results
$lastDataRow=1/5/2015 8:52,Success,CreatedVideo,best appliances in Boca Raton FL Date=01/05/2015 08:52:00 Status=Success Action=CreatedVideo Keyword=best appliances in Boca Raton FL $currentDateTime =01/05/2015 15:17:51 $dateTimeDiff=06:25:51.5232317 $minutesDiff=25 $totalMinutesDiff=385.858720528333 No video created for more than 15 minutes
Why would anyone want to get the last row of a file? I have a process that creates an mp4 video about every 1 to 1.5 minutes. When you do “Add-Content”, the data is written to the end of the file. (I show how I write data to this file in a previous blog: Logging Data Variables to a CSV File in Powershell) I want to write a separate process to monitor the progress by looking at the last row of the file. If no video is created for example, in 10 minutes, I know something has frozen up, and might need to kill and restart the process that creates the videos.
So the above code also shows how to compute the elapsed time, of the time the program runs to the last date in the CSV file. I ran the program at 3:17 pm, and the last date time in the CSV file was 8:52 this morning. Thus 6 hours, 25 minutes, and some-odd seconds has elapsed.
The above code also illustrates the why you might want to use the .TotalMinutes property instead of the .Minutes property. I want to know if more than 15 minutes have elapsed. Let’s suppose the elapse time was 1 hour and 7 minutes. I cannot just compare the 7 minutes to 15, I need to compare the 60+7 (or 67 minutes) to 15.