如何使用Perl替换文件中的行?

时间:2012-02-10 15:28:54

标签: perl

如何更改文件内容:

setenv api1000 Delhi
setenv CODEDROP regular
setenv RELEASETYPE build
setenv CDBUILD CD30

到此(在第二行替换字符串常规 CD29

setenv api1000 Delhi
setenv CODEDROP CD29
setenv RELEASETYPE build
setenv CDBUILD CD30

我的尝试:

my $CD_VER = CD29;

open RF, "<$OldFile" or die "Cannot open $OldFile for reading.";
open WF, ">$NewFile" or die "Cannot open $NewFile for writing.";

while ( <RF> ) {
    if (/CODEDROP/){
        if( /regular/) {
            $_ =~ s/regular/$CD_VER/ ;
            print WF "$_";      
        }
    }

close RF;
close WF;

copy("$NewFile","$OldFile");  # both became same

输出我在目标文件中得到如下:

setenv api1000 Delhi
setenv CODEDROP regular   ( I NEED  to REMOVE this LINE )
setenv CODEDROP CD29       ( only this line should be there )
setenv RELEASETYPE build
setenv CDBUILD CD30

3 个答案:

答案 0 :(得分:2)

如果这就是它所做的一切,那么你可以做一个单行:

perl -pe 's:(\bCODEDROP\s+)regular:$1CD29:' oldfile > newfile

如果您愿意,您甚至可以就地编辑文件:

perl -i.bak -pe 's:(\bCODEDROP\s+)regular:$1CD29:' oldfile

答案 1 :(得分:2)

您的代码唯一的实际问题是您在循环中的错误位置将行打印到新文件。您需要将旧文件中的每一行打印到新文件中。

稍微整理了你的文件并更新了一些习语,我最终得到了这个:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my $old_file = 'in.txt';
my $new_file = 'out.txt';

my $CD_VER = 'CD29';

open my $rf, '<', $old_file or die "Cannot open $old_file for reading.";
open my $wf, '>'. $new_file or die "Cannot open $new_file for writing.";

while ( <$rf> ) {
    if (/CODEDROP/ and /regular/) {
        s/regular/$CD_VER/ ;
    }
    print $wf $_;
}

close $rf;
close $wf;

答案 2 :(得分:1)

while (<RF>) {
    if (/CODEDROP\s+regular/) {
        $_ =~ s/regular/$CD_VER/ ;
    }
    print WF "$_";
}