[positioning a file handle]
This finds the lines correctly but if I try to print after $gpg_line,
the line below gets fubar.
I know I could use Tie::File, but i really want to understand what's
going on and how to insert my line after $gpg_line correctly.
Well, you can't.
A file is really a sequence of bytes, no more, no less. You can
append to the end of a file, but writing anywhere else implies
overwriting what's already there.
Duh... Yeah I feel dumb : P I don't know why I thought I could just
print the line.
Pity we can no longer refer to the FAQ for this question.
Perlfaq5 "How do I change one line in a file/delete a line..." used to
explain this problem in detail. These days it just refers to Tie::File,
another tool that makes files look like a sequence (a Perl array) of lines.
Yeah, Tie::File is great, but I needed to learn the steps in writing my
own parser, for future projects.
While, I've figured out what I needed to do and I'll paste the last of
the code below... I still don't understand what if ( ( $. == $base_line
... /gpgkey\=/i ) =~ /E/ ) { translates too.
It looks like $. == $base_line go down using .. until we hit gpgkey,
and I have no idea what the /E/ means. I'd really like to understand
that.
Code:
use strict;
use Fcntl;
use File::Copy;
my $file = "CentOS-Base.repo";
sysopen( REPO_FILE, $file, O_RDWR )
|| die "Can't open repo file !: $!\n";
my ( $base_line, $gpg_line, $found_exclude, $excluded, $exclude_line,
$package_excluded );
my $package = $ARGV[0];
print "$package\n";
while (<REPO_FILE>) {
chomp $_;
if ( $_ =~ /\[base\]/i ) {
$base_line = $.;
print "Found $_ on line $base_line\n";
}
if ( ( $. == $base_line .. /gpgkey\=/i ) =~ /E/ ) {
print "Found $_ on line $.\n";
$gpg_line = $.;
}
if ( ( $. == $gpg_line .. /exclude\=.*/i ) =~ /E/ ) {
$exclude_line = $.;
$found_exclude = 1;
print "Found exclude $_ on line $.\n";
$package_excluded = 1 if ($_ =~ m/.*$package.*/);
$excluded = $_;
}
}
# reopen (maybe seek() would be better? )
sysopen( REPO_FILE, $file, O_RDWR )
|| die "Can't open repo file !: $!\n";
sysopen( TEMP_REPO_FILE, "/tmp/repo.XXX", O_CREAT | O_WRONLY )
|| die "Can't create temporary shadow file: $!\n";
while (<REPO_FILE>) {
if ($found_exclude && !$package_excluded) {
if ( $. == $exclude_line ) {
chomp $_;
$_ =~ s/$_/$_ $package\n/;
}
}
else {
if ( $. == $gpg_line ) {
print TEMP_REPO_FILE "exclude\=$package\n" unless
$found_exclude;
}
}
print TEMP_REPO_FILE $_;
}
close TEMP_REPO_FILE;
close REPO_FILE;
copy( "/tmp/repo.XXX", $file );
unlink("/tmp/repo.XXX");
Thanks