Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl file handles - overwrite existing data instead of appending/deleting

cat -E test1.txt

output:

car$
$
$

I want just change "car" with "bike" and remove new/empty lines.

This is working as expected:

#!/usr/bin/perl -w
open(FILE1,"<","./test1.txt"); @araj=<FILE1>; close(FILE1);
open(FILE2,">","./test1.txt");
map {
s@car@bike@; s@^\n@@;
} @araj;
print(FILE2 @araj);
close(FILE2);

and

cat -E test1.txt

output is 100% correct for me:

bike$

But in above case i am using 2x opening/close file. So i am using 2x file handles.
I want to use only 1x file handle
(it`s for learning purposes, just trying to understand how +> +>> >> are working...).
For example:

#!/usr/bin/perl -w
open(FILE2,"+<","./test1.txt"); #what file handle should be here? +> , +>> >> .... ?
@araj=<FILE2>;
map {
s@car@bike@; s@^\n@@;
} @araj;
print(FILE2 @araj);
close(FILE2);

output is incorrect:

car$
$
$
bike$

Why this is appending, but no overwriting? When i used others file handles, results are also incorrect, for example empty file... Which file handle is used for read-and-overwrite ?

like image 355
rdbeni0 Avatar asked Sep 24 '17 16:09

rdbeni0


People also ask

How do you handle a file in Perl?

Perl - File I/O. The basics of handling files are simple: you associate a filehandle with an external entity (usually a file) and then use a variety of operators and functions within Perl to read and update the data stored within the data stream associated with the filehandle.

How do you append to a file in Perl?

Perl | Appending to a File. When a file is opened in write mode using “>”, the content of the existing file is deleted and content added using the print statement is written to the file. In this mode, the writing point will be set to the end of the file.

What are the three basic filehandles in Perl?

The three basic FileHandles in Perl are STDIN, STDOUT, and STDERR, which represent Standard Input, Standard Output, and Standard Error devices respectively. File Handling is usually done through the open function. FileHandle- The reference to the file, that can be used within the program or until its closure.

How to delete all content of a file using Perl core function?

This article shows how to do this using core perl function. There is a more modern and more readable way using Path::Tiny . open(my $fh, '>', 'report.txt') or die ... Opening a file for writing using the > sign will delete the content of the file if it had any. open(my $fh, '>>', 'report.txt') or die ...


2 Answers

Why this is appending, but no overwriting?

You have first read all the data until the end of the file. This mean the file position for the next read or write is now after all the data you have read, i.e. at the end of the file. If you want to write data from the beginning of the file you need to change the file position by using seek:

 seek($filehandle,0,0); # position at beginning of file

The next data you write will then be written starting with this new file position, i.e. from the beginning of the file. Once you are done you might need to remove any data after the current file position from the file by using truncate with the current file position you've got with tell:

 truncate($filehandle, tell($filehandle));

Or, the whole program:

use strict;
use warnings;
open(my $fh, "+<", "./test1.txt");
my @araj = <$fh>;
for(@araj) {
    s{car}{bike};
    s{^\n}{};
}
seek($fh, 0, 0);           # seek at the beginning of the file
print $fh @araj;
truncate($fh, tell($fh));  # remove everything after current file position
close($fh);
like image 102
Steffen Ullrich Avatar answered Oct 19 '22 00:10

Steffen Ullrich


After you read file in array the filehandle position is end of the file. Then you should change filehandle position by seek function (set on start of the file) perldoc seek. Next resize you file by truncate perldoc truncate

#!/usr/bin/perl -w
open(FILE2,"+<","./test1.txt"); #what file handle should be here? +> , +>> >> .... ?
@araj=<FILE2>;
map {
s@car@bike@; s@^\n@@;
} @araj;

seek(FILE2, 0, 0);
print(FILE2 @araj);
truncate(FILE2, tell(FILE2));

close(FILE2);
like image 37
ilux Avatar answered Oct 19 '22 00:10

ilux