Hi,

I am trying to search for a line in a file, comment that line using a " * " and finally append the range of corresponding lines extracted from the same file. The corresponding extracted range of lines maybe present before or after the line (which is to be commented).

Below is my file Test.txt

   Data to be ignored 
   Data to be ignored

   PERFORM P5X98A-PGM-INITS. # This line needs to be commented with a *
   #Append a copy of the corresponding extracted range of lines here.
   Data to be ignored
   Data to be ignored

   P5X98A-PGM-INITS SECTION.
   data to be stored 1
   data to be stored 1
   P5X98A-PGM-INITS-EXIT. EXIT.

   P5X98A-ABC-LIMIT SECTION. 
   Data to be stored 2
   Data to be stored 2
   P5X98A-ABC-LIMIT-EXIT. EXIT

   Data to be ignored 
   Data to be ignored 

   PERFORM P5X98A-ABC-LIMIT.  # This line needs to be commented with a *
   #Append a copy of the corresponding extracted range of lines here.
   Data to be ignored 
   Data to be ignored

Below is my code.

my $j=0;
open FILE1, "+<Test.txt" or die "Cannot open Test.txt!";

while (<FILE1>) {

  if (/$secarr[$j]/../$exarr[$j]/) {


    next if /$secarr[$j]/ || /$exarr[$j]/;

    if(my $dummy =~  s/^$perform[$j]/* $perform[$j]/)
   {
    print FILE1 $_;
   }     

  }
 $j++;
}

Where @secarr & @exarr contains the start and end strings. And @perform array contains all the lines starting with PERFORM statements.

Thanks in advance,

Dani AI

Generated

— concise, reliable approach and a few pitfalls to watch for. is right that the original question needed clearer intent; here’s a practical pattern that works whether the target SECTION block is before or after the PERFORM line.

Read the whole file into memory, index the section ranges first, then produce a new output stream: when a PERFORM line is encountered write a commented copy of that PERFORM and then append a copy of the indexed section lines. Advantages: you never try to mutate the file while iterating it (which corrupts positions), you avoid per-line counters that get out of sync, and you can canonicalize names (strip trailing dots, normalize case) so matches are robust.

Example implementation (adjust the regexes to match your exact COBOL-like labels):

use strict;
use warnings;

my $file = 'Test.txt';
open my $in, '<', $file or die $!;
my @lines = <$in>;
close $in;

# build section index
my %section;
for my $i (0..$#lines) {
  if ($lines[$i] =~ /^\s*(\S+)\b.*\bSECTION\b/i) {
    my $name = $1; $name =~ s/\.$//;
    for my $j ($i+1..$#lines) {
      if ($lines[$j] =~ /\b\Q${name}\E-EXIT\b/i) { $section{$name} = [$i, $j]; last }
    }
  }
}

# create new content
my @out;
for my $line (@lines) {
  if ($line =~ /^\s*PERFORM\s+(\S+)/i) {
    my $name = $1; $name =~ s/\.$//;
    push @out, '* ' . $line;                  # commented PERFORM
    if (my $r = $section{$name}) {
      push @out, @lines[$r->[0] .. $r->[1]];  # append a copy of the section
    }
  } else {
    push @out, $line;
  }
}

open my $out, '>', "$file.new" or die $!;
print $out @out;
close $out;
rename "$file.new", $file or die $!;

Notes and troubleshooting: enable strict/warnings, work on a backup copy first, normalize label tokens (remove trailing dots, case), avoid appending the same block multiple times unless intended, and handle missing EXIT markers gracefully (fallback could be next SECTION or end-of-file). This pattern eliminates issues like operating on an undefined temporary, incrementing counters per line instead of per match, and unsafe in-place writes.

Hi,
I believe there are alot of people that are willing to help if your question is clear enough.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.