How to append content of a file multiple times into one file in perl script

Viewed 233

I have a sample.txt file placed in directory say /output_files with some content in it. I want to create a new file say sample_new.txt and add the contents of sample.txt multiple times based on some condition.

For example:

  1. Create new file sample_new.txt
  2. For condition <1..3>
  3. Add the content of sample.txt into sample_new.txt files 3 times as the loop will run 3 times.

I tried with below script, but it doesn't work:

my $sample_file = "/output_files/sample.txt";
my $new_sample_file  = "/output_files/sample_new.txt";
          
#For loop --running say 3 times
open my $IN, '<', $sample_file  or die $!;
open my $OUT, '>>', $new_sample_file or die $!;
            
while (<$IN>) {
    s/\b(hld_cf_id)\b/1234/g; #replacing some content while writing
    print {$OUT} $_;
}
close $OUT or die $!;
#close loop;
2 Answers

Use a loop such as below. Write the header and the footer outside the loop. I refactored the code slightly to fit best Perl practices, but otherwise your code is OK. Note that you open your output file for appending. Not sure if that's intended. Perhaps you mean to open for writing: open my $out_fh, '>', $new_sample_file or die $!;


use strict;
use warnings;

my $sample_file = "/output_files/sample.txt";
my $new_sample_file  = "/output_files/sample_new.txt";
my $header = <<EOF;
a
b
c
EOF

my $footer = <<EOF;
x
y
z
EOF

open my $out_fh, '>>', $new_sample_file or die $!;
print {$out_fh} $header;

for my $num_samples ( 1..3 ) {
    open my $in_fh, '<', $sample_file  or die $!;
    while ( <$in_fh> ) {
        s/\bhld_cf_id\b/1234/g; # replacing some content while writing
        print {$out_fh} $_;
    }
}

print {$out_fh} $footer;
close $out_fh or die $!;

If it's a small file, you can just read the entire thing into a scalar and print it out as many times as needed. Modules like File::Slurper and Path::Tiny make this easy, you might also see people use an idiom like $data = do { local $/; open my $file, "<", "sample.txt"; <$file> };.

For big files, you might open it once, and then when you need to write its contents to another file, use a loop and then seek back to the beginning for the next time:

open my $sample, "<", "sample.txt";
...
# Inside an outer loop
# Read in 8k chunks instead of by lines
while (read $sample, my $line, 8192) {
    print $otherfile $line;
}
seek $sample, 0, 0;
Related