在文件中搜索单词并在Perl中替换

时间:2015-11-27 08:50:25

标签: perl

我想替换" a" to" red"在a.text文件中。我想编辑同一个文件,所以我尝试了这个代码,但它不起作用。我哪里错了?

@files=glob("a.txt");
foreach my $file (@files)
{
    open(IN,$file) or die $!;
    <IN>;
    while(<IN>)
    {
       $_=~s/a/red/g;
       print IN $file;
    }

   close(IN)
}

2 个答案:

答案 0 :(得分:5)

我建议在sed模式下使用perl可能更容易:

perl -i.bak -p -e 's/a/red/g' *.txt

-i是就地编辑(-i.bak将旧版保存为.bak - -i,而没有说明者不创建备份 - 这通常不太好理念)。

-p创建一个循环,迭代一次一行指定的所有文件($_),在打印该行之前应用-e指定的任何代码。在这种情况下,s///会将sed样式的patttern替换应用于$_,因此会运行搜索并替换每个.txt文件。

Perl使用<ARVG><>来做一些魔术 - 它会检查你是否在命令行中指定文件 - 如果你这样做,它会打开它们并迭代它们。如果您不这样做,则会从STDIN读取。

所以你也可以这样做:

 somecommand.sh | perl -i.bak -p -e 's/a/red/g' 

答案 1 :(得分:1)

在您的代码中,您使用相同的文件句柄来编写您用于打开文件阅读的文件句柄。为写入模式打开相同的文件,然后写入。

始终使用词法文件句柄和三个参数来打开文件。这是您修改后的代码:

use warnings;
use strict;

my @files = glob("a.txt");
my @data;
foreach my $file (@files)
{
    open my $fhin, "<", $file or die $!;
    <$fhin>;
    while(<$fhin>)
    {
        $_ =~ s/\ba\b/red/g;
        push @data, $_;
    }
    open my $fhw, ">", $file or die "Couldn't modify file: $!";
    print $fhw @data;
    close $fhw;
}

这是另一种方式(在标量中读取整个文件):

foreach my $file (glob "/path/to/dir/a.txt")
{
    #read whole file in a scalar
    my $data = do {
        local $/ = undef;
        open my $fh, "<", $file or die $!;
        <$fh>;
    };
    $data =~ s/\ba\b/red/g; #replace a with red,

    #modify the file
    open my $fhw, ">", $file or die "Couldn't modify file: $!";
    print $fhw $data;
    close $fhw;
}