我想替换" 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)
}
答案 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;
}