[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: Concernant:Re: [MacPerl] Counting the number of lines in a document



At 13:28 27/04/96 -0400, Stephane.Jose@uqam.ca wrote:

>Is it possible to read a particular line number from a file? If you
>already know which line contains the value you are looking for it must be
>faster to return directly that line instead of cycling through the file
>until there's a match.
>
>How can I implement something like '$myline = line 8 of MYFILE' in proper perl?
>
>I'd like to avoid loading the whole file into an array since the file I am
>using can be very large.

To which, among others, Tim Endres <time@ice.com> replied:

>You either have to make your lines fixed-length records,
>and use the seek command to locate the line to be read
>(i.e., seek( HDL, ($line * $record_length), 0 )  ), or
>you have to keep an index file alongside the data file
>that tells you the location of the start of each line
>in the file. I prefer fixed-length records when they do
>not involve huge storage penalties.


Sorry to take so lon,g to reply, but I've had other things on my mind.


Personally, I detest the use of fixed length records, unless the length of
the fields is garanteed to fall between some narrow limits. If you provide,
say, 40 characters for a name, this will be far to much in most cases, while
sometimes it still isn't enough.

You could end up with a file that's 3 times as large as it should be. A lot
if it's several Mb.


I like the "tabbed text" approach. This is the format spreadsheets use, when
"saving as a text file". This is: all of the row on a single line, with tabs
between the cells.

This has the advantage that it wastes no unnecessary space, while there is
*allways* enough room. Also, you can open and even edit your file in a
spreadsheet (like Excel).


But I just wondered: how do you get to your number "8"? How do you *know*
the data you need is on the eighth line?

My guess is that at startup of the script, your program reads through the
file, storing a key field (by which you recognize which record you want) as
the key of an associative array (="hashes"), and the record number (8) as
the value.

This is just silly. Why don't you just *ask* Perl where the current line is
(before reading it) using tell(), and store *this* value instead. 

No need to calculate the correct position any more. Just use it in a seek()
statement, and read your line.

Here's a demo script (save as droplet, and drop a text file on it):

### seek'n'tell
$i=4; # just some value
$file=$ARGV[0];
$index[0]=0;
while(<>) {
   print;
   push(@index,tell(ARGV));
}

open(IN,$file);
seek(IN,$index[$i],0);
$_=<IN>;
print "Line $i is: $_";

##end of script##


Hope this helps!



Bart Lateur,
Gent (Belgium)

--- Embracing the KIS principle: Keep It Simple