Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl: Writing file at Nth position

Tags:

perl

I am trying to write in to file at Nth POSITION. I have tried with below example but it writes at the end. Please help to achieve this.

#!/usr/bin/perl

open(FILE,"+>>try.txt")
or
die ("Cant open file try.txt");

$POS=5;

   seek(FILE,$POS,0);

   print FILE "CP1";
like image 210
vrbilgi Avatar asked Sep 08 '10 11:09

vrbilgi


3 Answers

You are opening the file in read-write appending mode. Try opening the file in read-write mode:

my $file = "try.txt";
open my $fh, "+<", $file
    or die "could not open $file: $!";

Also, note the use of the three argument open, the lexical filehandle, and $!.

#!/usr/bin/perl

use strict;
use warnings;

#create an in-memory file
my $fakefile = "1234567890\n";
open my $fh, "+<", \$fakefile
    or die "Cant open file: $!";

my $offset = 5;

seek $fh, $offset, 0
    or die "could not seek: $!";

print $fh "CP1";

print $fakefile;

The code above prints:

12345CP190
like image 145
Chas. Owens Avatar answered Nov 15 '22 13:11

Chas. Owens


If I understand you correctly, if the file contents are

123456789

you want to change that to

1234CP157689

You cannot achieve that using modes supplied to open (regardless of programming language).

You need to open the source file and another temporary file (see File::Temp. Read up to the insertion point from the source and write the contents to the temporary file, write what you want to insert, then write the remainder of the source file to the temporary file, close the source and rename the temporary to the source.

If you are going to do this using seek, both files must be opened in binary mode.

Here is an example using line oriented input and text mode:

#!/usr/bin/perl

use strict; use warnings;
use File::Temp qw( :POSIX );

my $source = 'test.test';
my $temp = tmpnam;

open my $source_h, '<', $source
    or die "Failed to open '$source': $!";

open my $temp_h, '>', $temp
    or die "Failed to open '$temp' for writing: $!";

while ( my $line = <$source_h> ) {
    if ( $line =~ /^[0-9]+$/ ) {
        $line = substr($line, 0, 5) . "CP1" . substr($line, 5);
    }
    print $temp_h $line;
}

close $temp_h
    or die "Failed to close '$temp': $!";

close $source_h
    or die "Failed to close '$source': $!";

rename $temp => $source
    or die "Failed to rename '$temp' to '$source': $!";
like image 36
Sinan Ünür Avatar answered Nov 15 '22 12:11

Sinan Ünür


this works for me

use strict;
use warnings;

open( my $fh, '+<', 'foo.txt' ) or die $!;

seek( $fh, 3, 0 );

print $fh "WH00t?";

this is also a more "modern" use of open(), see http://perldoc.perl.org/functions/open.html

The file will be closed when $fh goes out of scope ..

like image 2
Øyvind Skaar Avatar answered Nov 15 '22 12:11

Øyvind Skaar