Perl 如何使用单个文件句柄修改文件内容

Perl 如何使用单个文件句柄修改文件内容,perl,filehandle,Perl,Filehandle,我正在尝试使用Perl修改文件的内容 下面的脚本工作正常 #!/usr/bin/perl use strict; use warnings; open(FH,"test.txt") || die "not able to open test.txt $!"; open(FH2,">","test_new.txt")|| die "not able to opne test_new.txt $!"; while(my $line = <FH>) { $lin

我正在尝试使用Perl修改文件的内容

下面的脚本工作正常

#!/usr/bin/perl

use strict;
use warnings;

open(FH,"test.txt") || die "not able to open test.txt $!";
open(FH2,">","test_new.txt")|| die "not able to opne test_new.txt $!";

while(my $line = <FH>)
{
        $line =~ s/perl/python/i;
        print FH2 $line;
}
close(FH);
close(FH2);
test\u new.txt中的输出:

im learning perl
im in File handlers chapter
im learning python
im in File handlers chapter
im learning perl
im learning python
 chapter
 chapter
如果我试图使用相同的文件句柄来修改文件的内容,那么我就不会得到预期的输出。以下是尝试执行此操作的脚本:

#!/usr/bin/perl

use strict;
use warnings;

open(FH,"+<","test.txt") || die "not able to open test.txt $!";

while(my $line = <FH>)
{
        $line =~ s/perl/python/i;
        print FH $line;
}
close(FH);

如何使用单个文件句柄修改文件内容?

如@Саа27所示

这是perl onliner愉快地使用的典型情况

perl-i-pe's/perl/python/i'

perl
采用以下选项

  • -p
    :逐行循环(每行分配到
    $\u
    并在计算后打印
    $\u
  • -e
    :计算上述循环中的代码块(regex将
    $作为默认操作数)
  • -i
    :在plcae文件编辑中(如果为-i传递参数,perl将保留具有该扩展名的原始文件)
如果您在脚本下面运行

perl-i.bak-pe's/perl/python/i'test.txt

您将被修改
test.txt

im learning python
im in File handlers chapter
并获取名为
test.txt.bak

im learning perl
im in File handlers chapter

正如@Саа27所回答的那样

这是perl onliner愉快地使用的典型情况

perl-i-pe's/perl/python/i'

perl
采用以下选项

  • -p
    :逐行循环(每行分配到
    $\u
    并在计算后打印
    $\u
  • -e
    :计算上述循环中的代码块(regex将
    $作为默认操作数)
  • -i
    :在plcae文件编辑中(如果为-i传递参数,perl将保留具有该扩展名的原始文件)
如果您在脚本下面运行

perl-i.bak-pe's/perl/python/i'test.txt

您将被修改
test.txt

im learning python
im in File handlers chapter
并获取名为
test.txt.bak

im learning perl
im in File handlers chapter

不能从文件中删除(结尾处除外)。
不能在文件中插入字符(结尾处除外)

您可以替换文件中的字符。
您可以附加到文件。
您可以缩短文件。
就这样

您可以简单地将文件中的“Perl”替换为“Python”。它们的长度不同,因此需要在文件中插入字符,而您不能这样做

通过将文件的其余部分加载到内存中,并进一步将其写回两个字符,可以有效地将字符插入到文件中。但是对于非常大的文件,这样做会变得很棘手。由于每次要插入字符时都会复制文件的一部分(可能非常大),因此速度也非常慢

就地修改的另一个问题是无法从错误中恢复。如果发生了什么,您将留下一个不完整或损坏的文件

如果文件很小,如果出现问题,您可以丢失数据,最简单的方法是将整个文件加载到内存中

 open(my $fh, '<+', $qfn)
    or die("Can't open \"$qfn\": $!\n");

 my $file = do { local $/; <$fh> };

 $file =~ s/Perl/Python/g;

 seek($fh, 0, SEEK_SET)
    or die $!;
 print($fh $file)
    or die $!;
 truncate($fh)
    or die $!;

open(my$fh),您不能从文件中删除(末尾除外)。
不能在文件中插入字符(结尾处除外)

您可以替换文件中的字符。
您可以附加到文件。
您可以缩短文件。
就这样

你想象你可以简单地在文件中用“Python”替换“Perl”,它们的长度不同,因此需要在文件中插入字符,而你不能这样做

通过将文件的其余部分加载到内存中,再将其写回两个字符,可以有效地将字符插入到文件中。但是,对于非常大的文件来说,这样做会很棘手。这也非常缓慢,因为每次要插入字符时,都会复制文件的一部分(可能非常大)

就地修改的另一个问题是,您无法从错误中恢复。如果出现问题,您将留下一个不完整或损坏的文件

如果文件很小,如果出现问题,您可以丢失数据,最简单的方法是将整个文件加载到内存中

 open(my $fh, '<+', $qfn)
    or die("Can't open \"$qfn\": $!\n");

 my $file = do { local $/; <$fh> };

 $file =~ s/Perl/Python/g;

 seek($fh, 0, SEEK_SET)
    or die $!;
 print($fh $file)
    or die $!;
 truncate($fh)
    or die $!;

打开(我的$fh,'在实践中,您总是希望写入另一个文件,即使是
perl-i-pe's/perl/python/i'test.txt
也是这样工作的。或者,您可以一次读取整个文件,进行更改,然后将整个文件写回同一个句柄。@ССk k 27您能否解释一下命令i-i-peIt的文件句柄中的选项是什么,而不是处理程序。您有完整的,这里还有另一个演示如何保持相同的inode。在实践中,您总是希望写入另一个文件,即使是
perl-i-pe的/perl/python/i'test.txt也是这样工作的。或者,您可以一次读取整个文件,进行更改,然后将整个文件写回同一个句柄。@ССа解释命令中选项的作用是什么,即-i-peIt的文件句柄,而不是handler。您有完整的,这里还有另一个说明如何保持相同的inode。请注意,这使用了两个句柄。请注意,这使用了两个句柄。