There is no reason to read file into memory
$ cat 2
1
2
3
4
$ perl -i.orig -p -l -e "print 'three' if /3/" 2
$ cat 2
1
2
three
3
4
$ cat 2.orig
1
2
3
4
$ perl -MO=Deparse -i.orig -p -l -e "print 'three' if /3/"
BEGIN { $^I = ".orig"; }
BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = <ARGV>)) {
chomp $_;
print 'three' if /3/;
}
continue {
print $_;
}
-e syntax OK
| [reply] [d/l] |
So here is what I have. This just appends the end of the file which is close but not what I need. I need to add fileA in the MIDDLE of FileB
#!/usr/bun/perl
#------------------------------
# This script searches for "search"
# and adds lines from fileSource to fileOutput
use warnings;
use strict;
#use Fcntl (:flock :seek);
# Check
unless(-e $ARGV[0] || -e $ARGV[1]){
print("Please Enter A Valid File Name\n");
exit 1;
}
#if($ARGV[0] == "--help"){
# print("Usage is:\n");
# print("perl conference_add.pl <Source File> <Output File> <Sear
+ch String>");
#}
# assigns file path to local variables
my($fileSource) = $ARGV[0];
my($fileOutput) = $ARGV[1];
my(@inputLines);
# opens files for reading/writing
open(FILESOURCE, "<", $fileSource) || die("Can not open $fileSource $!
+");
open(FILEOUT, ">>", $fileOutput) || die ("Can not open $fileOutput $!"
+);
@inputLines = <FILESOURCE>;
print FILEOUT @inputLines;
close(FILESOURCE);
close(FILEOUT);
| [reply] [d/l] |
#!/usr/bin/perl
use strict;
use warnings;
( @ARGV == 3 and -f $ARGV[0] )
or die "Usage: $0 primary.file secondary.file insertion_point_
+pattern\n";
open( my $in1, "<", $ARGV[0] ) or die "$ARGV[0]: $!\n";
open( my $in2, "<", $ARGV[1] ) or die "$ARGV[1]: $!\n";
open( my $out, ">", "$ARGV[1].including.$ARGV[0]" )
or die "$ARGV[1].including.$ARGV[0]: $!\n";
while ( <$in2> ) {
print $out $_; # assuming you want content added after target p
+attern
if ( /$ARGV[2]/ and $in1 ) {
while ( <$in1> ) {
print $out $_;
}
close $in1;
$in1 = undef;
}
}
You might want to include a couple of "rename" steps after the outer while loop (rename the old "secondary.file" to "secondary.file.old", rename the output file to "secondary.file").
Note that if the given pattern never matches anything in the secondary file, the primary file never gets read or added to the output (output will be identical to input). | [reply] [d/l] |
Perhaps it is more clear if we give you an algorithm rather than a script:
- Open your output file (say fileC)
- Open your fileB
- Read through fileB file line by line, finishing if all lines have been read.
- Have you reached the place of insertion? If no, print to your output file, the line just read and go back to 3. If yes, open fileA and print all of it to your output file.
A rather minimal version of this algorithm could be: use strict;
use warnings;
open my $FILEC, '>', 'fileC';
open my $FILEB, '<', 'fileB';
open my $FILEA, '<', 'fileA';
while (my $line = <$FILEB>) {
do {local $_; print $FILEC $_ while (<$FILEA>)} if $line =~ m/INSE
+RT BEFORE HERE/;
print $FILEC $line;
}
By using a while loop both on the original file and the file to be inserted you never have more than a few lines in memory, so it will work on any size of file.
Of course you should add some tests to see whether opening of the files and writing to them succeeds.
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James
| [reply] [d/l] [select] |