in reply to In-place editing of files (was: general perl question)

Several respondents seem to be skirting the issues here. How do I open a file for reading and writing and edit on a per line basis?

One element of this that most people foget is that it is possible to make the file smaller with search and replace operations. That means you have to truncate the file length.

Here is my code:

use IO::File qw( &SEEK_SET ); my $fh = IO::File->new("+<foo.out") or die "failed to open file: $!"; while (<$fh>) { my $line = $_; chomp $line; $line =~ s/foo/f/g; push @output, $line; } my $output = join("\n", @output); $fh->seek( 0 , SEEK_SET ); $fh->print($output, "\n"); $fh->truncate( length($output) ); $fh->close; exit 0;
Clearly, this code walks the file while building up the new output. Then we reset the file position to the beginning; write over the old file contents; and truncate the file length to be the same size as the new contents. If we don't do the last step we might have left over garbage at the end of the file.

TIMTOWTDI: Here is a non-OO way:

use Fcntl qw( &SEEK_SET ); open(FH, "+<foo.out") or die "failed to open file"; while (<FH>) { my $line = $_; chomp $line; $line =~ s/foo/f/g; push @output, $line; } my $output = join("\n", @output); seek(FH, 0 , SEEK_SET ); print FH $output, "\n"; truncate(FH, length($output) ); close(FH); exit 0;