Insert Multiple Lines after a Specified Line -- Please Help!

  • Thread starter annie.promthana
  • Start date
A

annie.promthana

I am new to PERL (mostly use UNIX Krn Shell) I am trying to automate
some file manipulation techniques.
I have figured out how to Delete and Append Lines in a file, but I
can't figure out how to insert in this partcular way.

I want to insert a few lines after a line that I specify.

For Example:
The file contains the following contents:
ABCDEFG
HIJKLMNO
PQRSTUV
WXYZ

As a driver file, I have created updates I want to make to my existing
file, where "IA" is the line I want to insert after, and "IL" are the
lines that need to be inserted. The two digit number just helps in
defining the group they belong to. (Maybe to help for looping?)

IA00:HIJKLMNO
IL00:12345
IL00:67890
IA01:pQRSTUV
IL01:24680
IL01:13579

The new file should result as:
ABCDEFG
HIJKLMNO
12345
67890
PQRSTUV
24680
13579
WXYZ

I am sure I am making the script more complicated as it is. For some
reason, I am confused with the variables and generating dynamic ones
to name the arrays. (That is if I split the file into parts).

# IF THE INSTRUCTIONS ARE TO INSERT A LINE
if ($update_line =~ /^I\w\d\d:/)
{
open (my $INPUT, "<$origfile") or die "$! error.";

my $group;
my $afterline;

if ($line[0] =~ /^IA/) # if matched the first line to be changed
{
$group=substr($line[0], 2);
$afterline=$line[1];

open (my $update, "<$update_file") or die "$! error.";
while ( <$update> )
{
my @insert_lines =( grep ("IL$group:", $line));
}

print "GROUP: $group";
print "AFTER: $afterline";
print "INSERT: \n @insert_lines";
print "LINE: \n @line";

close $update;

print $insert_lines[1];

open (my $OUTPUT, ">$baseline_dir/$dwmm_file.new") or die "$!
error.";

while (<$INPUT>) {
print $OUTPUT $_;
print $OUTPUT @line[1] if $_ =~ /$insert_lines[1]/;
}

while( <$INPUT> ) # print the rest of the lines
{
print $OUTPUT $_;
}

close $OUTPUT;
}

close $INPUT;
}


I COULD EASILY DO THIS IN KRN SHELL, because of the lovely grep and
cat. All I do is cut up files.

total_inserts=`cat $update_file | grep "^IA[0-9][0-9]" | cut -c 3-4 |
paste -s -d" " -`

# Initialize the Counter
for i in ${total_inserts}
do
# Get the total number of records in the Original File
total_records=`cat $orig_file | wc -l`
check_integer $total_records

# Check that one value of line count is returned
check_variable $total_records

# Get the record that the file needs to be inserted
after
insert_after=`cat $update_file | grep "^IA$i" | cut -
d":" -f2`
# Check that there is a value in insert_after
check_variable $insert_after
check_record_exists "${insert_after}"

# Find the line number of the record the file needs to
be inserted after
head_records=`grep -n "^$insert_after" $orig_file |
tail -1 | cut -d":" -f1`

# Check that there is a value in head records
check_variable $head_records

# Calculate the tail lines for splitting PART 2
tail_records=`expr $total_records - $head_records`
# Check that there is a value in tail records
check_variable $tail_records

# Concatenate PART1(First half of the file) to a file
cat $orig_gile | head -"$head_records" > part-1-$i
# Check that part1 exists

# Concatenate PART2(the new inserts) to a file
cat $update_file | grep "^IL$i" | cut -d":" -f2 >
part-2-$i
# Check that part2 exists

# Concatenate PART3(Bottom half of the file) to a file
cat $orig_file | tail -"$tail_records" > part-3-$i
# Check that part3 exists

# Concatenate all of the files together (Top Half,
Inserts, Bottom Half)
cat part-1-$i part-2-$i part-3-$i > final-$i.txt
# Check that all parts exist, then check if final
exists

# Work with the modified version of the dwmm file
orig_file=final-$i.txt

done


Any ideas would be appreciated. Maybe suggestions that my technique is
not right?
 
J

John W. Krahn

I am new to PERL (mostly use UNIX Krn Shell) I am trying to automate
some file manipulation techniques.
I have figured out how to Delete and Append Lines in a file, but I
can't figure out how to insert in this partcular way.

I want to insert a few lines after a line that I specify.

For Example:
The file contains the following contents:
ABCDEFG
HIJKLMNO
PQRSTUV
WXYZ

As a driver file, I have created updates I want to make to my existing
file, where "IA" is the line I want to insert after, and "IL" are the
lines that need to be inserted. The two digit number just helps in
defining the group they belong to. (Maybe to help for looping?)

IA00:HIJKLMNO
IL00:12345
IL00:67890
IA01:pQRSTUV
IL01:24680
IL01:13579

The new file should result as:
ABCDEFG
HIJKLMNO
12345
67890
PQRSTUV
24680
13579
WXYZ

$ echo "ABCDEFG
HIJKLMNO
PQRSTUV
WXYZ" | \
perl -pe'
$_ .= "12345\n67890\n" if /^HIJKLMNO$/;
$_ .= "24680\n13579\n" if /^PQRSTUV$/;
'
ABCDEFG
HIJKLMNO
12345
67890
PQRSTUV
24680
13579
WXYZ



John
 
U

Uri Guttman

ap> I am new to PERL (mostly use UNIX Krn Shell) I am trying to automate
ap> some file manipulation techniques.
ap> I have figured out how to Delete and Append Lines in a file, but I
ap> can't figure out how to insert in this partcular way.

ap> I want to insert a few lines after a line that I specify.

ap> As a driver file, I have created updates I want to make to my existing
ap> file, where "IA" is the line I want to insert after, and "IL" are the
ap> lines that need to be inserted. The two digit number just helps in
ap> defining the group they belong to. (Maybe to help for looping?)

ap> IA00:HIJKLMNO
ap> IL00:12345
ap> IL00:67890
ap> IA01:pQRSTUV
ap> IL01:24680
ap> IL01:13579

ap> The new file should result as:
ap> ABCDEFG
ap> HIJKLMNO
ap> 12345
ap> 67890
ap> PQRSTUV
ap> 24680
ap> 13579
ap> WXYZ

either:

use Tie::File ;
tie @lines, 'Tie::File', $filename or die "can't tie::file $file $!" ;

that will make your file look like a perl array and you can loop,
delete, splice in new lines with perl's normal array stuff. it would be
much easier than what you are doing now.

another approach is to slurp in the file into an array with:

use File::Slurp ;
my @lines = read_file( $filename ) ;

and then manipulate the array (same as with tie::file) and then write
out the modified array back to the file with:

write_file( $filename, @lines ) ;

either way is so much simpler than yours as you can use splice() to do
all the hard work. find the N lines to be inserted at one point and a
single splice() call will put them there. same for deletions. this
reduces your code to a simple parser of your change lines and a splice
calls for each set of related changes.

uri
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top