 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Laszlo
Joined: 14 Feb 2005 Posts: 4668 Location: Boulder, CO
|
Posted: Fri Dec 16, 2005 3:37 pm Post subject: Tail: the last lines of a text file |
|
|
The last few lines of a text file are often needed, like at checking a log file for a specific entry. Here is a short script for it. | Code: | Tail(k,file) ; Return the last k lines of file
{
Loop Read, %file%
{
i := Mod(A_Index,k)
L%i% = %A_LoopReadLine%
}
L := L%i%
Loop % k-1
{
IfLess i,1, SetEnv i,%k%
i-- ; Mod does not work here
L := L%i% "`n" L
}
Return L
} | Test it with | Code: | | MsgBox % Tail(3, A_ScriptFullPath) | For only the last line of a file, the following 2-line script is enough | Code: | Loop Read, %A_ScriptFullPath%
L = %A_LoopReadLine% |
For small files the following version might be faster (Serenity's solution). It reads the file into a variable and parses it from memory. For large files the version above is better, because it scans the file only once, and keeps only k lines in memory. | Code: | Tail(k,file) ; Return the last k lines of file
{
FileRead text, %file%
Loop Parse, text, `n
lines++
Loop Parse, text, `n
{
If (A_Index < lines - k)
Continue
L = %L%`n%A_Loopfield%
}
StringTrimLeft L, L, 1
Return L
} |
|
|
| Back to top |
|
 |
pin Guest
|
Posted: Fri Dec 16, 2005 4:07 pm Post subject: |
|
|
Bookmarked!
Can i ask a question here? How to loop and send msgbox when file size is changed, or new lines are added to current %file%.
ie: when log.txt is changed(new lines are added) it send msgbox |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4668 Location: Boulder, CO
|
Posted: Fri Dec 16, 2005 5:45 pm Post subject: |
|
|
| Code: | #Persistent
Settimer FileCheck
FileCheck:
FileGetSize Size, %A_ScriptFullPath% ; put your filename here
If Size0 >= %Size%
Return
If Size0 =
{
Size0 = %Size%
Return
}
MsgBox File size increased!
Size0 = %Size%
Return |
|
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 950
|
Posted: Sun Apr 12, 2009 9:50 am Post subject: |
|
|
I posted at an other thread a version without loop and regex. May be you are interested in testing. Not sure how faster (or slower) it can be.
http://www.autohotkey.com/forum/viewtopic.php?t=43104
This is the one getting last line only:
| Code: | str_getTailf(ByRef _Str) {
Return SubStr(_Str,InStr(_Str,"`n",False,0)+1)
} |
This is the one with n lines (here called _LineNum):
| Code: | str_getTail(_Str, _LineNum = 1)
{
StringGetPos, Pos, _Str, `n, R%_LineNum%
StringTrimLeft, _Str, _Str, % ++Pos
Return _Str
} |
|
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 950
|
Posted: Sun Apr 12, 2009 10:55 am Post subject: |
|
|
Here is a comparison of the functions.
Anyway here is my benchmark result:
| Quote: | | Code: | str_getTailf (by Tuncay): 188
str_getTail (by Tuncay): 469
StrTail /loop (by strictlyfocused02): 16750
Tail /regex (by Laszlo): 1062 |
|
This is the script and the functions used to benchmark:
| Code: | Text := "`n`n`n"
Loop, 100000
Text .= "`nLine " . A_Index
StartTime := A_TickCount
Loop, 100
str_getTailf(Text)
ElapsedTime1 := A_TickCount - StartTime
StartTime := A_TickCount
Loop, 100
str_getTail(Text)
ElapsedTime2 := A_TickCount - StartTime
StartTime := A_TickCount
Loop, 100
StrTail(1,Text)
ElapsedTime3 := A_TickCount - StartTime
StartTime := A_TickCount
Loop, 100
Tail(1,Text)
ElapsedTime4 := A_TickCount - StartTime
out =
(
str_getTailf (by Tuncay):`t`t%ElapsedTime1%
str_getTail (by Tuncay):`t`t%ElapsedTime2%
StrTail /loop (by strictlyfocused02):`t%ElapsedTime3%
Tail /regex (by Laszlo):`t`t%ElapsedTime4%
)
MsgBox, 1, Benchmark results, Ok copies to clipboard`n`n%out%
IfMsgBox Ok
Clipboard := out
RETURN
str_getTailf(ByRef _Str) {
Return SubStr(_Str,InStr(_Str,"`n",False,0)+1)
}
str_getTail(_Str, _LineNum = 1)
{
StringGetPos, Pos, _Str, `n, R%_LineNum%
StringTrimLeft, _Str, _Str, % ++Pos
Return _Str
}
StrTail(k,str) ;; Inspired by Laszlo (http://www.autohotkey.com/forum/topic6928.html)
{
Loop,Parse,str,`n
{
i := Mod(A_Index,k)
L%i% = %A_LoopField%
}
L := L%i%
Loop,% k-1
{
If i < 1
SetEnv,i,%k%
i-- ;Mod does not work here
L := L%i% "`n" L
}
Return L
}
Tail(k,str) {
Return RegExReplace(str,".*(?=(\n[^\n]*){" k "}$)")
} |
edit: updated the Tail function from Laszlo
Last edited by Tuncay on Sun Apr 12, 2009 6:27 pm; edited 2 times in total |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4668 Location: Boulder, CO
|
Posted: Sun Apr 12, 2009 4:41 pm Post subject: |
|
|
The point of this 3.5 years old thread was to get the last line of a text file, without keeping the whole file in memory. Even if the file fits to the RAM, the memory usage gets large, which may cause other applications to slow down.
During the last three years we learned how to seek and read only portions of the file, so there are much faster methods for huge files. |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 950
|
Posted: Sun Apr 12, 2009 4:48 pm Post subject: |
|
|
| Oh I did not looked at the date... how I came to this thread?? |
|
| Back to top |
|
 |
vla
Joined: 12 May 2007 Posts: 28
|
Posted: Thu May 14, 2009 8:12 pm Post subject: |
|
|
| Code: | Text =
(
Text of Line 1
Text of Line 2
Text of Line 3
Text of Line 4
Text of Line 5
Text of Line 6
Text of Line 7
Text of Line 8
Text of Line 9
Text of Line 10
Text of Line 11
Text of Line 12
Text of Line 13
Text of Line 14
Text of Line 15
)
MsgBox,% StrTail(4,Text)
;Return the last (k) lines of (str)
StrTail(k,str) ;; Inspired by Laszlo (http://www.autohotkey.com/forum/topic6928.html)
{
Loop,Parse,str,`n
{
i := Mod(A_Index,k)
L%i% = %A_LoopField%
}
L := L%i%
Loop,% k-1
{
If i < 1
SetEnv,i,%k%
i-- ;Mod does not work here
L := L%i% "`n" L
}
Return L
} |
Using that code how do i get the var "text" to be a file? I do not fully understand this code, i am changing a few things to see what happens.
Changing the MsgBox,% StrTail(4,Text) into a 1 i get the last line, but what var is that saved under? %strtail?
i figured out the first question, use fileread. Still don't know exactly how the variable on that works. |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4668 Location: Boulder, CO
|
Posted: Thu May 14, 2009 8:51 pm Post subject: |
|
|
It is a function call, its result is not saved, unless you write something like | Code: | | MyVar := StrTail(4,Text) |
|
|
| Back to top |
|
 |
vla
Joined: 12 May 2007 Posts: 28
|
Posted: Thu May 14, 2009 8:54 pm Post subject: |
|
|
| perfect! thank you so much, i love you all. |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4668 Location: Boulder, CO
|
Posted: Thu May 14, 2009 9:08 pm Post subject: |
|
|
btw, you can write the original function more compactly | Code: | Tail(k,file) { ; Return the last k lines of file
Loop Read, %file%
i := Mod(A_Index,k), L%i% := A_LoopReadLine
Loop % k
i := Mod(i+1,k), L .= L%i% "`n"
Return L
} |
|
|
| Back to top |
|
 |
guest3456 Guest
|
Posted: Mon Jun 07, 2010 4:43 am Post subject: |
|
|
| Laszlo wrote: |
During the last three years we learned how to seek and read only portions of the file, so there are much faster methods for huge files. |
i found this one:
http://de.autohotkey.com/forum/topic4619.html |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|