Hi, I have a file which contains some lines of text. What I want to do is after the first two lines, insert a new sentence. So if the original file looks something like this:

Sachin
Ganguly
Dravid
Laxman
Sehwag

after the insertion, I want it to look like this:

Sachin
Ganguly
foo
Dravid
Laxman
Sehwag

I came up with this code:

open f, "+< t.txt";
while (<f>) {
if (1..2) { print; }
else { last; }
}
print f "foo";
close f;

but when I run it, instead of the desired output, I get this:

Sachin
Ganguly
Dravid
Laxman
SehwagSachin
Ganguly
Dravid
foo

Notice that the first three lines have been appended to the last line, after which foo is printed out. Can anyone point out where am In erring, and what might be the correct way?

My best guess is the filehandle holds all the data that has been read until you write. Looks like you might have to either find a different way or just read it in first and the write it again.

EDIT:
after looking around for a bit it seems to be fairly difficult (see this for more details http://bumppo.net/lists/macperl-anyperl/1999/08/msg00062.html).
The following code will attempt to write after the second line, however it overwrite whatever is there.

use strict;
use warnings "all";

my $counter = 0;
open my $FILE, "+<t.txt";
while(<$FILE>)
{   
    if($counter == 1)
    {
        my $pos = tell($FILE);
        seek($FILE, $pos, 0);
        print $FILE "foo";
        last;
    }
    $counter++;
}
close $FILE;

Edited 4 Years Ago by replic: reason

For this sort of task I would prefer using inplace-edit instead of read-write mode.

#!/usr/bin/perl
use strict;
use warnings;

if (@ARGV == 0){
    my $filename = 'test.txt';
    #So you can use diamond operator and inplace editing
    push @ARGV, $filename;
    warn "No file name argument so I assume you want to edit $filename.\n"
}

#Enable inplace editing. Copy of input file saved as 'test.txt.bk'
$^I = ".bk";

while (<>) {
    chomp;
    print "$_\n";
    if ($. == 2){
        print "foo\n"; 
    }
}

You can do it more simply but a clever use of bash scripting from within the perl script. This is not strictly perl, but when working in Linux I found these kind of solutions shorter and faster:

    my $linecounter=2; # insert the new text line after this line
    my $text2insert="foo";
    my $filename="myfile.txt";
    my $file_lines=`cat $filename | wc -l `; # total number of lines in the file
    system("head -$linecounter > tmpfile.txt");
    system("echo $text2insert >> tmpfile.txt");
    my $rest_of_file=$file_lines-$linecounter; # calculate how many lines remain to add after the new text
    system("tail -$rest_of_file >> tmpfile.txt");
    system("mv tmpfile.txt $filename"); # overwrite the old file

head -[num] will print out the first [num] lines in the file. Then you use the echo command to print the line you want to insert.
Lastely, you may use the tail -[remaining_lines] to append the rest of the file after the new insert.
Only thing is that it is not clean perl. But if you are working in linux it is a useful workaround.

-FH

P.S.
Sorry but for some reason I don't get the nice perl coding format that previous posts had :\

Edited 4 Years Ago by FelineHazard: Code makers

This article has been dead for over six months. Start a new discussion instead.