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

Discussion in 'Perl Misc' started by annie.promthana@gmail.com, May 4, 2007.

  1. Guest

    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?
    , May 4, 2007
    #1
    1. Advertising

  2. wrote:
    > 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
    --
    Perl isn't a toolbox, but a small machine shop where you can special-order
    certain sorts of tools at low cost and in short order. -- Larry Wall
    John W. Krahn, May 4, 2007
    #2
    1. Advertising

  3. Uri Guttman Guest

    >>>>> "ap" == annie promthana <> writes:

    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

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, May 4, 2007
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. KK
    Replies:
    2
    Views:
    528
    Big Brian
    Oct 14, 2003
  2. Replies:
    1
    Views:
    439
    Jonathan Mcdougall
    Dec 6, 2005
  3. mortb
    Replies:
    3
    Views:
    130
    mortb
    Dec 3, 2004
  4. vasanth kumar
    Replies:
    1
    Views:
    108
    Evertjan.
    Oct 3, 2004
  5. Cah Sableng
    Replies:
    0
    Views:
    231
    Cah Sableng
    Apr 23, 2007
Loading...

Share This Page