#----------------------------- |
# looking for line number $DESIRED_LINE_NUMBER |
$. = 0; |
do { $LINE = <HANDLE> } until $. == $DESIRED_LINE_NUMBER || eof ; |
#----------------------------- |
@lines = <HANDLE>; |
$LINE = $lines [ $DESIRED_LINE_NUMBER ]; |
#----------------------------- |
# usage: build_index(*DATA_HANDLE, *INDEX_HANDLE) |
sub build_index { |
my $data_file = shift ; |
my $index_file = shift ; |
my $offset = 0; |
while (< $data_file >) { |
print $index_file pack ( "N" , $offset ); |
$offset = tell ( $data_file ); |
} |
} |
# usage: line_with_index(*DATA_HANDLE, *INDEX_HANDLE, $LINE_NUMBER) |
# returns line or undef if LINE_NUMBER was out of range |
sub line_with_index { |
my $data_file = shift ; |
my $index_file = shift ; |
my $line_number = shift ; |
my $size ; # size of an index entry |
my $i_offset ; # offset into the index of the entry |
my $entry ; # index entry |
my $d_offset ; # offset into the data file |
$size = length ( pack ( "N" , 0)); |
$i_offset = $size * ( $line_number -1); |
seek ( $index_file , $i_offset , 0) or return ; |
read ( $index_file , $entry , $size ); |
$d_offset = unpack ( "N" , $entry ); |
seek ( $data_file , $d_offset , 0); |
return scalar (< $data_file >); |
} |
# usage: |
open (FILE, "< $file" ) or die "Can't open $file for reading: $!\n" ; |
open ( INDEX , "+>$file.idx" ) |
or die "Can't open $file.idx for read/write: $!\n" ; |
build_index(*FILE, * INDEX ); |
$line = line_with_index(*FILE, * INDEX , $seeking ); |
#----------------------------- |
use DB_File; |
use Fcntl ; |
$tie = tie ( @lines , $FILE , "DB_File" , O_RDWR, 0666, $DB_RECNO ) or die |
"Cannot open file $FILE: $!\n" ; |
# extract it |
$line = $lines [ $sought - 1]; |
#----------------------------- |
# download the following standalone program |
#!/usr/bin/perl -w |
# print_line-v1 - linear style |
@ARGV == 2 or die "usage: print_line FILENAME LINE_NUMBER\n" ; |
( $filename , $line_number ) = @ARGV ; |
open (INFILE, "< $filename" ) or die "Can't open $filename for reading: $!\n" ; |
while (<INFILE>) { |
$line = $_ ; |
last if $. == $line_number ; |
} |
if ($. != $line_number ) { |
die "Didn't find line $line_number in $filename\n" ; |
} |
print ; |
#----------------------------- |
# download the following standalone program |
#!/usr/bin/perl -w |
# print_line-v2 - index style |
# build_index and line_with_index from above |
@ARGV == 2 or |
die "usage: print_line FILENAME LINE_NUMBER" ; |
( $filename , $line_number ) = @ARGV ; |
open (ORIG, "< $filename" ) |
or die "Can't open $filename for reading: $!" ; |
# open the index and build it if necessary |
# there's a race condition here: two copies of this |
# program can notice there's no index for the file and |
# try to build one. This would be easily solved with |
# locking |
$indexname = "$filename.index" ; |
sysopen (IDX, $indexname , O_CREAT|O_RDWR) |
or die "Can't open $indexname for read/write: $!" ; |
build_index(*ORIG, *IDX) if -z $indexname ; # XXX: race unless lock |
$line = line_with_index(*ORIG, *IDX, $line_number ); |
die "Didn't find line $line_number in $filename" unless defined $line ; |
print $line ; |
#----------------------------- |
# download the following standalone program |
#!/usr/bin/perl -w |
# print_line-v3 - DB_File style |
use DB_File; |
use Fcntl ; |
@ARGV == 2 or |
die "usage: print_line FILENAME LINE_NUMBER\n" ; |
( $filename , $line_number ) = @ARGV ; |
$tie = tie ( @lines , "DB_File" , $filename , O_RDWR, 0666, $DB_RECNO ) |
or die "Cannot open file $filename: $!\n" ; |
unless ( $line_number < $tie -> length ) { |
die "Didn't find line $line_number in $filename\n" |
} |
print $lines [ $line_number -1]; # easy, eh? |
#----------------------------- |