Jump to content

FileReadLine - can you read second last line?


 Share

Recommended Posts

Here are another couple of methods to return individual lines from the end of a file.

Local $sFile = "test.txt"
; http://www.autoitscript.com/forum/topic/143295-filereadline-can-you-read-second-last-line/page__st__20#entry1009431

ConsoleWrite(@LF & "===== File Name ======================================" & @LF)
ConsoleWrite("The first line      > " & _FileReadLine($sFile) & @LF) ; Returns first line.
ConsoleWrite("The first line      > " & _FileReadLine($sFile, "") & @LF) ; Returns first line (file handle not used).
ConsoleWrite("The last line    > " & _FileReadLine($sFile, -1) & @LF) ; Returns last line.
ConsoleWrite("The penultimate line> " & _FileReadLine($sFile, -2) & @LF) ; Returns penultimate line.
ConsoleWrite("The third last line > " & _FileReadLine($sFile, -3) & @LF) ; Returns third last line.

ConsoleWrite(@LF & "===== File handle ==================================" & @LF)
Local $file = FileOpen($sFile, 0)

ConsoleWrite("The first line      > " & _FileReadLine($file) & @LF) ; Returns first line.
ConsoleWrite("The second line    > " & _FileReadLine($file, "") & @LF) ; Returns first line (file handle not used).
ConsoleWrite("The last line    > " & _FileReadLine($file, -1) & @LF) ; Returns last line.
ConsoleWrite("The penultimate line> " & _FileReadLine($file, -2) & @LF) ; Returns penultimate line.
ConsoleWrite("The third last line > " & _FileReadLine($file, -3) & @LF) ; Returns third last line.

FileClose($file)

ConsoleWrite(@LF & "=== 2 StringInStrs =====================================" & @LF)
ConsoleWrite("The last line    > " & _FileReadEndLine($sFile, -1) & @LF) ; Returns last line.
ConsoleWrite("The penultimate line> " & _FileReadEndLine($sFile, -2) & @LF) ; Returns penultimate line.
ConsoleWrite("The third last line > " & _FileReadEndLine($sFile, -3) & @LF) ; Returns third last line.

Local $s = FileRead($sFile)
If StringRegExp($s, "v$") = 0 Then $s &= @LF
ConsoleWrite(@LF & 'Three-liner RegExp returns the penultimate line> "' & _
        StringRegExpReplace( $s, "^(V*R)+(V*)((V*R){2})", "2") & '"' & @LF)


Func _FileReadLine($sFile, $iLine = "")
    If $iLine = "" Or $iLine = Default Then ; Successive calls with these parameters increments line number, only when used in conjunction with a file handle.
        Return FileReadLine($sFile)
    ElseIf $iLine < -1 Then
        FileSetPos($sFile, 0, 0);$FILE_BEGIN = 0 from FileConstants.au3 and NOT from Constants.au3 as help file says.
        Local $s = FileRead($sFile)
        If StringRegExp($s, "v$") = 0 Then $s &= @LF
        Return StringRegExpReplace($s, "^(V*R)+(V*)((V*R){" & (-1 * $iLine) & "})$", "2")
    Else
        Return FileReadLine($sFile, $iLine)
    EndIf
EndFunc   ;==>_FileReadLine

Func _FileReadEndLine($sFile, $iLine = -1)
    Local $s = FileRead($sFile)
    If StringRegExp($s, "v$") = 0 Then $iLine += 1
    Local $Fst = StringInStr($s, @LF, 2, $iLine - 1) + 1
    Return StringMid($s, $Fst, (StringInStr($s, @LF, 2, $iLine)) - $Fst)
EndFunc   ;==>_FileReadEndLine

Edit: Adjusted script so that correct results are returned when there is also no trailing linefeed in file.

Edited by Malkey
Link to comment
Share on other sites

$FILE_BEGIN is in Constants.au3 as FileConstants.au3 is included.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

#include <FileConstants.au3>
$Pos = 200

$hFile = FileOpen(@ScriptFullPath)

FileSetPos($hFile, -$Pos, $FILE_END)
$sText = FileRead($hFile)
FileClose($hFile)

While 1
    $string = _ReadString($Pos)
    MsgBox(0, '', $string)
    ; ClipPut($string)
    If $Pos<1 Then ExitLoop
WEnd

Func _ReadString(ByRef $Pos)
    $TmpPos = StringInStr($sText, @CRLF, 0, -1, $Pos, $Pos)
    $string = StringMid($sText, $TmpPos + 2, $Pos - $TmpPos - 2)
    $Pos = $TmpPos
    Return $string
EndFunc

Edited by AZJIO
Link to comment
Share on other sites

Here another one

#include <File.au3>
$sFile = @ScriptDir & "Testfile.txt"
$hFile = FileOpen($sFile, 2)
Global $sTxt
For $i = 1 To $iLines
    $sTxt &= "Line number " & $i & @CRLF
Next
FileWrite($hFile, $sTxt)
FileClose($hFile)

MsgBox(0, "Test", GetLineContent($sFile, _FileCountLines($sFile) - 1))


Func GetLineContent($sFile, $iLineNum)
 Return StringRegExpReplace(FileRead($sFile), "^(.*v+?|$){" & $iLineNum & "}(?s).*", "$1")
EndFunc

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

I never tested it with huge lines!

Anyway, when I run this I get an error: AutoIT3.exe ended.rc:-1073741571 (0xC00000FD).

#include <File.au3>
$sFile = @ScriptDir & "Testfile.txt"

$iLines = 3957 ;3957 - 4096 is crashing the script and above 4096 the whole string will be displayed
$hFile = FileOpen($sFile, 2)
Global $sTxt
For $i = 1 To $iLines
    $sTxt &= "Line number " & $i & @CRLF
Next
FileWrite($hFile, $sTxt)
FileClose($hFile)

$hFile = FileOpen($sFile)
$sString = FileRead($hFile)
FileClose($hFile)

MsgBox(0, "Test", GetLineContent($sString, $iLines - 1))

Func GetLineContent($sString, $iLineNum)
    Return StringRegExpReplace($sString, "^(.*v+?|$){" & $iLineNum & "}(?s).*", "$1")
EndFunc

$iLines from 3957 up to 4096 is crashing the script and above 4096 returns the whole string. Strange.

Seems to be a problem with StringRegExpReplace() and the iLineNum value. {x} seems to be limited to 3956.

Edit: {x} has a limited recursion stack which runs out of stack and crashes when the limit is reached!

Nice to have a one liner but not working properly for larger than 3956 lines :( So better forget this idea!

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Hi GUys

Thanks for all the great feedback. What i've done works but I also have all these options available to me.

So... which is the best? ;-)

Oh, and regarding my earlier question re event logs - I am still using my batch file method but with a string at the end of the file which must be present for my function to continue. :)

Link to comment
Share on other sites

  • 4 years later...
On 8/14/2012 at 10:29 AM, UEZ said:

I never tested it with huge lines!

 

Anyway, when I run this I get an error: AutoIT3.exe ended.rc:-1073741571 (0xC00000FD).

 

 

#include <File.au3>
$sFile = @ScriptDir & "Testfile.txt"

$iLines = 3957 ;3957 - 4096 is crashing the script and above 4096 the whole string will be displayed
$hFile = FileOpen($sFile, 2)
Global $sTxt
For $i = 1 To $iLines
    $sTxt &= "Line number " & $i & @CRLF
Next
FileWrite($hFile, $sTxt)
FileClose($hFile)

$hFile = FileOpen($sFile)
$sString = FileRead($hFile)
FileClose($hFile)

MsgBox(0, "Test", GetLineContent($sString, $iLines - 1))

Func GetLineContent($sString, $iLineNum)
    Return StringRegExpReplace($sString, "^(.*v+?|$){" & $iLineNum & "}(?s).*", "$1")
EndFunc

 

$iLines from 3957 up to 4096 is crashing the script and above 4096 returns the whole string. Strange.

 

Seems to be a problem with StringRegExpReplace() and the iLineNum value. {x} seems to be limited to 3956.

 

 

Edit: {x} has a limited recursion stack which runs out of stack and crashes when the limit is reached!

Nice to have a one liner but not working properly for larger than 3956 lines :( So better forget this idea!

 

 

 

Br,

UEZ

Exactly, as in the first post, the best solution is for big files, sometimes exceeding the AutoIt memory limits. So anything that Reads the whole file is not perferred, such as ReadFile($hFile) or _FileReadToArray()

 

On page 1 water already posted what looks like the best solution, and the fastest?

Edited by Biatu

What is what? What is what.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...