note
haukex
<blockquote><i>However, my script is simply appending the text to the output file (after counting 11 lines from the end).</i></blockquote>
<p>I initially couldn't reproduce this, <i>but</i> managed when running the script on Windows <i>and</i> the files having LF (not CRLF) line endings. Using <c>tie @records, 'Tie::File', "output.fem", recsep=>"\n";</c> makes it work again. (See also the module's [https://metacpan.org/release/Tie-File/source/lib/Tie/File.pm#L1261|<c>_default_recsep</c>].)</p>
<p><i>However,</i> I would not implement this script this way, since it requires you to know the correct place to insert the lines beforehand, and it requires there to be enough space for the lines to be inserted, otherwise data will be overwritten. The following uses a [id://11103827|state machine pattern], and has the advantages that it does a bit of verification on the input file (it checks that there's only one section of <c>NODE</c> lines) and that it doesn't care how many lines both the input files have. Also, it won't have the above issue, because normal [doc://open]s on Windows will normally do the right thing with line endings. Plus [mod://Tie::File] [id://1204204|adds significant overhead] to the program.</p>
<p>(<i>Update:</i> Shameless plug: If you want to overwrite the input file, then see my module [mod://File::Replace] for an easier/safer way to do so.)</p>
<c>
use warnings;
use strict;
my $DATAFILE = 'data.txt';
my $INSERTFILE = 'insert.txt';
my $OUTFILE = 'output.txt';
open my $ofh, '>', $OUTFILE or die "$OUTFILE: $!";
select($ofh); # "print"s will go to this handle now
open my $dfh, '<', $DATAFILE or die "$DATAFILE: $!";
my $state = 'before nodes';
while ( my $line = <$dfh> ) {
if ( $line =~ /^\s*NODE\b/ ) {
if ( $state eq 'before nodes' )
{ $state = 'in nodes'; }
elsif ( $state eq 'in nodes' ) { }
elsif ( $state eq 'after nodes' )
{ die "expected only one section of NODEs" }
else { die $state }
}
else {
if ( $state eq 'before nodes' ) { }
elsif ( $state eq 'in nodes' ) {
do_node_insert($INSERTFILE);
$state = 'after nodes';
}
elsif ( $state eq 'after nodes' ) { }
else { die $state }
}
print $line;
}
close $dfh;
sub do_node_insert {
my $file = shift;
open my $ifh, '<', $file or die "$file: $!";
while ( my $line = <$ifh> ) {
next unless $line =~ /^\s*NODE\b/;
print $line;
}
close $ifh;
}
</c>
<readmore title="input and output files">
<p><b><c>data.txt</c></b>:</p>
<c>
'Node ID X Y Z BC
NODE 1 4.51000 0.00000 79.00000
NODE 2 0.00000 0.00000 79.00000
NODE 3 0.00000 0.00000 78.27000
NODE 4 -1.88000 0.00000 78.27000
'Elem ID np1 np2 material geom lcoor ecc1
BEAM 1 2 1 2 36 2
BEAM 2 3 2 2 36 1
PIPE 19 4.489 0.022
PIPE 20 4.488 0.021
</c>
<p><b><c>insert.txt</c></b>:</p>
<c>
NODE 32 0.00000 0.00000 -1.90000
NODE 33 0.00000 0.00000 -5.50000
BEAM 26 27 26 1 14 1
</c>
<p><b><c>output.txt</c></b>:</p>
<c>
'Node ID X Y Z BC
NODE 1 4.51000 0.00000 79.00000
NODE 2 0.00000 0.00000 79.00000
NODE 3 0.00000 0.00000 78.27000
NODE 4 -1.88000 0.00000 78.27000
NODE 32 0.00000 0.00000 -1.90000
NODE 33 0.00000 0.00000 -5.50000
'Elem ID np1 np2 material geom lcoor ecc1
BEAM 1 2 1 2 36 2
BEAM 2 3 2 2 36 1
PIPE 19 4.489 0.022
PIPE 20 4.488 0.021
</c>
</readmore>
11123966
11123966