代码之家  ›  专栏  ›  技术社区  ›  brian d foy

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

  •  10
  • brian d foy  · 技术社区  · 16 年前

    人们一直在问这个问题,而我也一直用同样的答案来回答 perlfaq5 . 现在我们可以在Stackoverflow上指出这一点。

    1 回复  |  直到 16 年前
        1
  •  13
  •   Community Mohan Dere    6 年前

    从…起 perlfaq5 :

    插入、更改或删除文本文件中的行的基本思想包括读取并打印文件到要进行更改的位置,进行更改,然后读取并打印文件的其余部分。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 $_;
        }
    

    要跳过行,请使用循环控件。这个 next last 一旦遇到以下任一情况,将停止所有处理 __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::文件 我也能帮上忙。但是,如果可以,请避免一次读取整个文件。在进程完成之前,Perl不会将该内存返回给操作系统。

    inFile.txt ,用新内容覆盖文件。和 -p 虽然 -e -i 启用在位编辑。当前行正在运行 $_ -p $_ 在循环的末尾。看见 perlrun 更多细节。

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

    infire.txt ,给 -我 要添加的文件扩展名:

    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 转换就像 除了它不打印 $_

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

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