It's surprisingly hard to do that right. Not from the perl, but from the need to lock the file you're writing, and to avoid overwriting pieces of it.
I'm going to assume that the files are large enough that you won't want to slurp the whole thing into memory.
I use sysopen there to get the exclusive file open mode. If $fileC exists then there is an instance of your script working already (don't think it can't happen ;-). That's why I'm careful to delete $fileC before an error exit.#!/usr/bin/perl use warnings; use strict; use Fcntl qw/:DEFAULT :flock/; my $fileA = '/path/to/file_a.txt'; my $fileB = '/path/to/file_b.txt'; my $fileC = '/path/to/file_a.bak'; my $tagline = qr/\QFile A: *** Initial Temperature/; sysopen my $fc, $fileC, O_WRONLY | O_EXCL or die 'Competing process: ', $!; flock $fc, LOCK_EX | LOCK_NB or die 'Competing process: ', $!; open my $fa, '+<', $fileA or die $!; flock $fa, LOCK_EX; while (<$fa>) { print $fc $_; last if /^$tagline/; } open my $fb, '<', $fileB or unlink $fileC and die $!; print $fc $_ while <$fb>; close $fb or unlink $fileC and die $!; print $fc $_ while (<$fa>); close $fc or unlink $fileC and die $!; # reverse the order of the next two statements if # your system won't clobber the open file rename $fileC, $fileA; close $fa;
It's not easier to do if the files are small enough to slurp, just different. You'd then have the option of doing without the temporary file, but you'd have to seek to the beginning of $fa to write the new content. Inserting the new content would just be a string operation then, with lots of ways to do it.
Update: Modified the fail actions for opening and locking the temporary file. If there is a competing process or file, we want to stop and let the operator decide what to do.
After Compline,
Zaxo
In reply to Re: Writing in at a certain location in a file
by Zaxo
in thread Writing in at a certain location in a file
by newuser_perl
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |