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 ..