WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Files and Directories

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Extracting last lines of a file

Keywords:  UDS Extracting last lines of a file  reverse file read

Question:

I'm looking for the best/simplest/quickest way to extract the last few (e.g. 20) lines from a text file with a large (e.g. 30,000) and variable number of lines.

Answer:

Sometime ago i did 3 udfs for reverse fileread using a workaround for global variables(environment), now that we have UDS i changed the code.

UDS are FileOpenRev, FileReadRev and FileCloseRev, they work the same as the normal wil functions but in reverse mode.

Probably is slower than the previous code and it can be done better.

;Reverse fileread using UDS.
;This fuctions read a text file from the end to the beginnig, when the beginning 
;of the file is reached, the string *BOF* will be returned, they expect standard 
;DOS CR-LF terminated lines in the file.
;Blank lines are not returned.
;Usage: same as standard wil equivalent functions.
;Guido 02/02

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
;FileOpenRev : Opens a text file for reading.                                     ;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
;(s) file: name of the file to open                                               ;
;Returns:  filehandle                                                             ;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
#definesubroutine FileOpenRev(rev_file)
rev_size = filesize(rev_file)
rev_buf = binaryalloc(rev_size+4)
;read file at buffer offset 2 
BinaryReadEx(rev_buf, 2, rev_file, 0, rev_size)
;crlf at end if does not exist
if binarypeek2(rev_buf, rev_size)<>2573 then binarypoke2(rev_buf, rev_size+2, 2573)
;crlf at beginning if does not exist
if binarypeek2(rev_buf, 2)<>2573 then binarypoke2(rev_buf, 0, 2573)
;set global offset at the end of buffer
rev_globaloffset=rev_size+3
return rev_buf
#endfunction


;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
;FileReadRev : Reads data from a file.                                            ;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
;handle : same integer that was returned by FileOpenRev                           ;
;Returns: line of data read from file (blank lines not returned)                  ;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
#definesubroutine FileReadRev(rev_handle)
while 1
  rev_offset = BinaryIndexEx(rev_handle, rev_globaloffset, @crlf, @backscan, @false)
  rev_offset2 = BinaryIndexEx(rev_handle, rev_offset, @crlf, @backscan, @false)
  if rev_offset2==-1 then return "*BOF*"
  ;line = binarypeekstr(handle, offset2+2, offset-1-(offset2+1))
  rev_line = binarypeekstr(rev_handle, rev_offset2+2, rev_offset-rev_offset2)
  rev_globaloffset=rev_offset2+2
  if rev_line=="" then continue
  return rev_line
endwhile
#endfunction


;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
;FileCloseRev : Closes a file, frees the buffer and the variables used by the UDS.;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
;handle: same integer that was returned by FileOpen.                              ;
;Returns: always 0.                                                               ;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
#definesubroutine FileCloseRev(rev_handle)
binaryfree(rev_handle)
DropWild("rev_*")
return 0
#endfunction


;test: get last 10 lines of a file
file="c:\yourfile.txt"
handle = FileOpenRev(file)
c=0
while c<10
  line = FileReadRev(handle)
  if line=="*BOF*" then break
  c=c+1
  message("", line)
endwhile

FileCloseRev(handle)
message("", "done")
exit


Article ID:   W15328
File Created: 2002:09:05:13:51:20
Last Updated: 2002:09:05:13:51:20