However, my script is simply appending the text to the output file (after counting 11 lines from the end).
I initially couldn't reproduce this, but managed when running the script on Windows and the files having LF (not CRLF) line endings. Using tie @records, 'Tie::File', "output.fem", recsep=>"\n"; makes it work again. (See also the module's _default_recsep.)
However, 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 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 NODE 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 opens on Windows will normally do the right thing with line endings. Plus Tie::File adds significant overhead to the program.
(Update: Shameless plug: If you want to overwrite the input file, then see my module File::Replace for an easier/safer way to do so.)
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;
}
data.txt:
'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
insert.txt:
NODE 32 0.00000 0.00000 -1.90000
NODE 33 0.00000 0.00000 -5.50000
BEAM 26 27 26 1 14 1
output.txt:
'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
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.