Read and Write to a file in perl

感情迁移 提交于 2019-12-30 12:13:29

问题


    this
    is just
    an example.

Lets assume the above is out.txt. I want to read out.txt and write onto the same file.

    <Hi >
    <this>
    <is just>
    <an example.>

Modified out.txt. I want to add tags in the beginning and end of some lines. As I will be reading the file several times I cannot keep writing it onto a different file each time.

EDIT 1 I tried using "+<" but its giving an output like this :

Hi
this
is just
an example.
<Hi >
<this>
<is just>
<an example.>
 **out.txt**

EDIT 2 Code for reference :

open(my $fh, "+<", "out.txt");# or die "cannot open < C:\Users\daanishs\workspace\CCoverage\out.txt: $!";
     while(<$fh>)
     {
        $s1 = "<";
        $s2 = $_;
        $s3 = ">";
        $str = $s1 . $s2 . $s3;
        print $fh "$str";
     }

回答1:


The very idea of what you are trying to do is flawed. The file starts as

H  i  /  t  h  i  s  /  ...

If you were to change it in place, it would look as follows after processing the first line:

<  H  i  >  /  i  s  /  ...

Notice how you clobbered "th"? You need to make a copy of the file, modify the copy, the replace the original with the copy.

The simplest way is to make this copy in memory.

my $file;
{ # Read the file
   open(my $fh, '<', $qfn)
      or die "Can't open \"$qfn\": $!\n";
   local $/;
   $file = <$fh>;
}

# Change the file
$file =~ s/^(.*)\n/<$1>\n/mg;

{ # Save the changes
   open(my $fh, '>', $qfn)
      or die "Can't create \"$qfn\": $!\n";
   print($fh $file);
}

If you wanted to use the disk instead:

rename($qfn, "$qfn.old")
   or die "Can't rename \"$qfn\": $!\n";

open(my $fh_in, '<', "$qfn.old")
      or die "Can't open \"$qfn\": $!\n";
open(my $fh_out, '>', $qfn)
      or die "Can't create \"$qfn\": $!\n";

while (<$fh_in>) {
   chomp;
   $_ = "<$_>";
   print($fh_out "$_\n");
}

unlink("$qfn.old");

Using a trick, the above can be simplified to

local @ARGV = $qfn;
local $^I = '';
while (<>) {
   chomp;
   $_ = "<$_>";
   print(ARGV "$_\n");
}

Or as a one-liner:

perl -i -pe'$_ = "<$_>"' file



回答2:


Read contents in memory and then prepare required string as you write to your file. (SEEK_SET to zero't byte is required.

#!/usr/bin/perl

open(INFILE, "+<in.txt");
@a=<INFILE>;
seek INFILE, 0, SEEK_SET ;
foreach $i(@a)
{ 
    chomp $i;
    print INFILE "<".$i.">"."\n";
}

If you are worried about amount of data being read in memory, you will have to create a temporary result file and finally copy the result file to original file.




回答3:


You could use Tie::File for easy random access to the lines in your file:

use Tie::File;
use strict;
use warnings;

my $filename = "out.txt";
my @array;
tie @array, 'Tie::File', $filename or die "can't tie file \"$filename\": $!";

for my $line (@array) {
  $line = "<$line>";
  # or $line =~ s/^(.*)$/<$1>/g; # -- whatever modifications you need to do
}

untie @array;

Disclaimer: Of course, this option is only viable if the file is not shared with other processes. Otherwise you could use flock to prevent shared access while you modify the file.

Disclaimer-2 (thanks to ikegami): Don't use this solution if you have to edit big files and are concerned about performance. Most of the performance loss is mitigated for small files (less than 2MB, though this is configurable using the memory arg).




回答4:


One option is to open the file twice: Open it once read-only, read the data, close it, process it, open it again read-write (no append), write the data, and close it. This is good practice because it minimizes the time you have the file open, in case someone else needs it.

If you only want to open it once, then you can use the +< file type - just use the seek call between reading and writing to return to the beginning of the file. Otherwise, you finish reading, are at the end of the file, and start writing there, which is why you get the behavior you're seeing.




回答5:


Need to specify

use Fcntl qw(SEEK_SET);

in order to use

seek INFILE, 0, SEEK_SET;

Thanks user1703205 for the example.



来源:https://stackoverflow.com/questions/12633743/read-and-write-to-a-file-in-perl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!