Hashing Variable-Record-Length Files
######## Random-Access Variable-Length (Text) File Processing With Indexing
#!/usr/bin/perl
die "Usage: $0 filename\n" if @ARGV != 1;
open(F, "$ARGV[0]") || die "Cannot open $ARGV[0] for reading.\n";
die "File is empty!\n" if -z $ARGV[0];
$index = 1;
$offsets[$index] = 0; # Offsets[0] not assigned because there's no line zero!
$offsets[++$index] = tell(F) while (<F>);
$index--;
while(print ("Enter line numbers: "), ($_ = <STDIN>) !~ /^\s*quit\s*$/i)
{
next if /^\s*$/; # No response. Just re-prompt.
if ($_ !~ /^\s*\d+\s*(\d+\s*)?$/) # Must be one or two digit strings!
{
print "Legal entries consist of one or two positive integers!\n";
next;
}
@lines = m/\d+/g; # Gather the digit string(s).
$lines[1] = $lines[0] if @lines == 1;
if (($lines[0] > $index) || ($lines[1] > $index) || ($lines[0] == 0) ||
($lines[1] == 0))
{
print "Legal line numbers are 1 through $index!\n";
next;
}
if ($lines[1] < $lines[0])
{
print "Improper order of numbers.\n";
next;
}
# Go to offset of first user-specified line.
seek(F, $offsets[$lines[0]], 0);
open(MORE,"|more") || die "Cannot open more filter.\n";
foreach $linenum ($lines[0]..$lines[1])
{
printf MORE "%-5s:%s", $linenum, scalar(<F>);
}
close(MORE);
}
####################### Sample Program Session #########################
$ textindex.pl asg55.pl
Enter line numbers: 2 90
Legal line numbers are 1 through 58!
Enter line numbers: -1 10
Legal entries consist of one or two integers!
Enter line numbers: 2 25
2 :
3 : open(PHONE, "phonebook") || die "Could not open phonebook.\n";
4 :
5 : while (<PHONE>)
6 : {
7 : chomp($_);
8 : ($name, $ext) = split(/:/, $_);
9 : $byname{$name} = $ext;
10 : }
11 :
12 : %byext = reverse(%byname);
13 : close(PHONE);
14 :
15 : while (($name_or_ext = get_and_clean_name()) ne "Quit")
16 : {
17 : next if $name_or_ext =~ /^\s*$/;
18 : if ($name_or_ext =~ /^\d/) ##### It's an extension.
19 : {
20 : if (!exists($byext{$name_or_ext}))
21 : {
22 : print "Nobody has that extension.\n\n";
23 : }
[7m--More--[m ### Notice the "footprint" of more.
24 : else
25 : {
Enter line numbers: 8 6
Improper order of numbers.
Enter line numbers: 1111
Legal line numbers are 1 through 58!
Enter line numbers: 1 2 3
Legal entries consist of one or two positive integers!
Enter line numbers:
Enter line numbers: qUiT
$