Random File Access with Seek and Tell

#!/usr/bin/perl -w
#######################  Random Access Files   ######################

open(F, "+>demofile") || die "Cannot open demofile.\n";

while (print("Enter name: "), $name = <STDIN>)
{
     chomp($name);
     print "Enter age: ";
     chomp($age = <STDIN>);
     $buffer = sprintf "%-20s%4d\n",$name, $age;  #####  25-byte record.
     print F $buffer;
} 

$position = tell(F);  #####  Give offset from beginning of file after
                      #####  many 25-byte writes.
print "\nPosition is: $position\n";   ###### Should be num of writes * 25

seek(F, 0, 0);   #####  Effectively a rewind command.

$position = tell(F);
print "Position is: $position\n";    #####  Should be zero!

$line = <F>;
print "First line in the file is: $line\n";
seek(F, -(length($buffer)), 2);  #### Seek backwards one 25-byte record from EOF

$line = <F>;
print "\nLast line in the file is: $line\n";
close(F);             
########  New open modes:  +>  Create for writing and reading.
########                   +<  Open existing file for writing and reading.
########                   +>> Open for reading and writing. All writes 
########                       go to the end of file.
########
########  Warning!  You MUST do an intervening seek or tell when 
########  switching between read and write or vice versa!  File
########  pointer gets ALL MESSED UP if you fail to do so!!
########################  Output of Code above  ###########################

$ advfile.pl
Enter name: Bill Clinton
Enter age: 52
Enter name: Alexander the Great
Enter age: 24
Enter name:            #######  Hit Unix EOF (CTRL-D) here.

Position is: 50
Position is: 0

First line in the file is: Bill Clinton          52
Last line in the file is: Alexander the Great   24
############################  The $. Variable  ##############################

#!/usr/bin/perl -w

open(F, "+>garbage1") or die "Cannot open garbage1!\n";
print F "1\n2\n3\n";   ######  Write three lines.
seek(F, 0, 0);   #####  Rewind file.

while (<F>)
{
      print "$.\n";   ######  As output shows, it keeps the line number!
}
close F;

########  But what about with multiple files?  Let's experiment!!

open(F, ">garbage2") or die "Cannot open garbage2!\n";
print F "1\n2\n3\n";     ######  Write three lines.

open(F, ">garbage3") or die "Cannot open garbage3!\n";
print F "1\n2\n3\n";     ######  Write three lines.

close F;

#################  Use of $. With Multiple File Operations  #################
foreach $file (glob "garbage[2-3]")
{
     open(F, "$file") or die "Cannot open $file.\n";
     print "$.\n" while <F>;
} 
close F;
#########  Why didn't $. reset after the first file? 
#########  Need explicit close after print...while statement!

foreach $file (glob "garbage[2-3]")
{
     print "File is:$file\n";
     open(F, "$file") or die "Cannot open $file.\n";
     print "$.\n" while <F>;
     close F;
} 
##########################  Output of Code Above  #########################

1     ######  Print of line numbers of garbage1.
2
3

1     ######  Print of line numbers of garbage2 and garbage3.
2     ######  Why did $. not reset -- NEED TO CLOSE FILES!!!
3
4
5
6

File is:garbage2   ######  This time $. reset before printing line
1                  ######  numbers of garbage3.
2
3
File is:garbage3   ######  Notice that line numbers now start at 1, not 4!
1
2
3
#############################  New Use for ..  ##############################
#!/usr/bin/perl -w

open(F,"stuff") or die "Cannot open stuff.\n";
while (<F>) { print if 3..7; }    #####  If is true while 3 <= $. <= 7

#############################  Output Below  #################################


3       ######  Output of while(<F>) print if 3..7;
4       ######  File "stuff" is 1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n
5
6
7
###############  Use of Regular Expressions With .. and ...  ###############

#!/usr/bin/perl -w

open(F, "$ARGV[0]") or die "Cannot open $ARGV[0]!\n";

while (<F>)
{
    print if /#/../#/;   #####  Won't be what you want in all likelihood!
}

open(F, "$ARGV[0]") or die "Cannot open $ARGV[0]!\n";
print "*" x 50, "\n";   ####  Divider line between output of 1st and 2nd loops!

while (<F>)
{
    print if /#/.../#/;   #####  This ** is ** what you want in all likelihood!
}
############################  Program Output  #################################

$ dot.pl x    #####  Program invocation.

Contents of input file (x)
--------------------------

this is junk.
this is more junk.
#   abc  #
123
456
#   xyz  #
hi there
#  testing, testing! 
inside
outside
USA
#end of test
more garbage.

Screen Output
-------------

#   abc  
#   xyz  
#  testing, testing! 
#end of test
**************************************************
#   abc  
123
456
#   xyz  
#  testing, testing! 
inside
outside
USA
#end of test

########  The moral of this story?  If you're using /regexp/ then use ...
########  and not ..