0

我想使用 perl 读取和写入现有文件。

谁能告诉我为此目的我必须使用什么模式:我对以下可用模式感到非常困惑。我试过了,+>但它没有写入文件。

mode operand create truncate 
read     <   
write    >    ✓      ✓ 
append  >>    ✓  

mode       operand create truncate 
read/write  +<   
read/write  +>       ✓      ✓ 
read/append +>>      ✓  

例如:我有一个如下文件:

one
two 
four

我想在两者之间插入一条线:

one
two
three
four
4

3 回答 3

2

看看perlopentut关于混合读取和写入的内容。结论是混合模式打开模式都不是理想的,就地编辑模式(使用$^I)是更好的解决方案。

对于这个特殊问题,我推荐使用该Tie::File模块,它允许您将文件视为一个简单的数组。

例如,要将行three插入示例数据,请编写

use strict;
use warnings;

use Tie::File;

tie my @file, 'Tie::File', 'myfile.txt' or die $!;

splice @file, 2, 0, 'three';

untie @file or die $!;
于 2012-08-22T11:58:55.390 回答
1

perldoc for 中open,您有两个直接的问题:

+< 几乎总是首选用于读/写更新 - +> 模式将首先破坏文件。

您通常不能使用任何一种读写模式来更新文本文件,因为它们具有可变长度的记录。

更一般地说,您在尝试在文件中间插入数据时遇到了设计问题——文本文件不能这样工作。最简单的方法是:

  1. 将整个文件读入内存,然后将修改后的文件写入
  2. 逐行读取输入文件,将输出写入另一个经过修改的文件。然后删除原始文件并将新文件重命名为旧名称。

1) 是最简单的,但 2) 如果文件很大,则内存效率会更高。

编辑:还有一个-i开关允许 Perl 就地编辑文件。它通过在幕后为您实现 2) 来实现。但是,我个人更愿意坚持自己做。这似乎比它的价值更令人困惑。

于 2012-08-22T09:33:08.537 回答
1

就地文件插入可能有点困难,因为必须移动数据。请参阅dan1111关于如何以另一种方式实现目标的答案(这是首选方式)。

但是,为了就地插入:

#!/usr/bin/env perl

use strict;
use warnings;

my $file = 'input';
open my $fh, '+<', $file or die "Failed to open $file: $!";

my $pos, @remaining_lines;
while (<$fh>) {
    if ($pos) {
        push @remaining_lines, $_;
    }
    elsif (m{^two$/$}) {
        $pos = tell;
    }
}

my $word = 'three';
seek $fh, $pos, 0;
print $fh $word, $/, @remaining_lines;
于 2012-08-22T09:56:19.210 回答