在Perl中,如何在文件中更改,删除或插入行,或者附加到文件的开头?

时间:2010-12-08 14:00:50

标签: perl file insert append

我想通过修改,删除或插入行或附加到文件的开头来更改文件的内容。我怎么能在Perl中做到这一点?


这是来自questionofficial FAQ。我们是importing the perlfaq to Stack Overflow

1 个答案:

答案 0 :(得分:42)

(这是official perlfaq answer,减去任何后续修改)

从文本文件中插入,更改或删除行的基本思路 涉及阅读和打印文件到你想要的点 更改,进行更改,然后读取和打印文件的其余部分。 Perl不提供对行的随机访问(特别是自记录以来) 输入分隔符$/,是可变的),尽管模块如 Tie::File可以伪造它。

执行这些任务的Perl程序采用打开文件的基本形式, 打印它的行,然后关闭文件:

open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";

while( <$in> )
    {
    print $out $_;
    }

close $out;

在该基本表单中,添加您需要插入,更改或的部分 删除行。

要将行添加到开头,请在输入之前打印这些行 打印现有行的循环。

open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";

print $out "# Add this line to the top\n"; # <--- HERE'S THE MAGIC

while( <$in> )
    {
    print $out $_;
    }

close $out;

要更改现有行,请插入代码以修改其中的行 while循环。在这种情况下,代码找到所有小写版本的“perl” 并且将它们大写。每一行都会发生,所以请确保你是 应该在每一行都这样做!

open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";

print $out "# Add this line to the top\n";

while( <$in> )
    {
    s/\b(perl)\b/Perl/g;
    print $out $_;
    }

close $out;

要仅更改特定行,输入行号$。非常有用。 首先阅读并打印到您想要更改的行。接下来,阅读 要更改的单行,更改它并打印它。之后, 阅读其余部分并打印出来:

while( <$in> )   # print the lines before the change
    {
    print $out $_;
    last if $. == 4; # line number before change
    }

my $line = <$in>;
$line =~ s/\b(perl)\b/Perl/g;
print $out $line;

while( <$in> )   # print the rest of the lines
    {
    print $out $_;
    }

要跳过行,请使用循环控件。此示例中的下一个跳过 注释行,最后一次遇到所有处理 __END____DATA__

while( <$in> )
    {
    next if /^\s+#/;             # skip comment lines
    last if /^__(END|DATA)__$/;  # stop at end of code marker
    print $out $_;
    }

使用旁边的跳过来删除特定行 您不希望在输出中显示的行。这个例子跳过了每一个 第五行:

while( <$in> )
    {
    next unless $. % 5;
    print $out $_;
    }

如果由于一些奇怪的原因,你真的想立刻看到整个文件 而不是逐行处理,你可以啜饮它(只要你可以 适合整个事情!):

open my $in,  '<',  $file      or die "Can't read old file: $!"
open my $out, '>', "$file.new" or die "Can't write new file: $!";

my @lines = do { local $/; <$in> }; # slurp!

    # do your magic here

print $out @lines;

File::Slurp之类的模块 并且Tie::File可以帮助解决这个问题 太。但是,如果可以,请避免立即读取整个文件。 Perl不会 将该内存返回给操作系统,直到该过程结束。

您还可以使用Perl单行来就地修改文件。下列 在inFile.txt中将所有'Fred'更改为'Barney',用。覆盖文件 新内容。使用-p开关,Perl在代码周围包含一个while循环 您使用-e指定,-i启用就地编辑。目前 行在$_。使用-p,Perl会自动打印$_的值 循环结束。有关详细信息,请参阅perlrun

perl -pi -e 's/Fred/Barney/' inFile.txt

要备份inFile.txt,请为-i添加一个文件扩展名:

perl -pi.bak -e 's/Fred/Barney/' inFile.txt

要仅更改第五行,您可以添加一个测试检查$.输入 行号,然后仅在测试通过时执行操作:

perl -pi -e 's/Fred/Barney/ if $. == 5' inFile.txt

要在某一行之前添加行,您可以在之前添加一行(或多行!) Perl打印$_

perl -pi -e 'print "Put before third line\n" if $. == 3' inFile.txt

您甚至可以在文件的开头添加一行,因为当前行 在循环结束时打印:

perl -pi -e 'print "Put before first line\n" if $. == 1' inFile.txt

要在文件中已有的行之后插入一行,请使用-n开关。它的 就像-p一样,只是它不会在循环结束时打印$_,所以 你必须自己做。在这种情况下,首先打印$_,然后打印 你要添加的行。

perl -ni -e 'print; print "Put after fifth line\n" if $. == 5' inFile.txt

要删除行,只打印您想要的行。

perl -ni -e 'print unless /d/' inFile.txt