用perl修改文件中的字符串
我有一个文件,d00.dat,我需要更改d02的字符串d01…使用以下代码,它在控制台中打印修改,但在文件d00.dat中它们没有更改…我怎么做用perl修改文件中的字符串,perl,Perl,我有一个文件,d00.dat,我需要更改d02的字符串d01…使用以下代码,它在控制台中打印修改,但在文件d00.dat中它们没有更改…我怎么做 my $line = 0; my $filename = "d00.dat"; open(my $fh, '<', $filename) || die "file could not open $! \n"; while( $line = <$fh>) { if( $line =~ s/d01/d02/g ){ print "$lin
my $line = 0;
my $filename = "d00.dat";
open(my $fh, '<', $filename) || die "file could not open $! \n";
while( $line = <$fh>) {
if( $line =~ s/d01/d02/g ){
print "$line\n";
}
my$line=0;
我的$filename=“d00.dat”;
open(my$fh),最简单、最快的解决方案是将文件读入内存,进行更改,然后将更改写回文件
my $qfn = "d00.dat";
my $file;
{
open(my $fh, '<', $qfn)
or die("Can't open \"$qfn\": $!\n");
local $/;
$file = <$fh>;
}
$file =~ s/d01/d02/g;
{
open(my $fh, '>', $qfn)
or die("Can't create \"$qfn\": $!\n");
print($fh $file);
}
my $filename = "d00.dat";
open(my $fh, '<', $filename) || die "file could not open $! \n";
my @new_lines = map { s/d01/d02/g; $_ } <$fh>;
close $fh;
open(my $fh_out, '>', $filename) || die "file could not open $! \n";
print $fh_out $_ for @new_lines;
close $fh_out;
Perl有一个修改文件的开关。我想这就是您要寻找的:
perl -i.bak -p -e 's/d01/d02/g;' d00.dat
这将
- 将
d00.dat
重命名为d00.dat.bak
- 读取
d00.dat.bak
- 将每次出现的
d01
替换为d02
- 将结果行打印到
d00.dat
说明:
-i
在位编辑文件,并在给定后缀的情况下选择性地进行备份。
例如,-i.bak
将创建$file.bak
,-i.before
将创建$file.before
等。
没有后缀(只有<代码> -I/COD>),将没有备份,因此认为这是危险的。
-p
放置一个类似
while(<>) {
# your code
print;
}
while(){
#你的代码
印刷品;
}
在本例中,围绕您的代码(s/../…/g;
)
-e
仅表示“执行以下语句”
如果您正在考虑仅更改这些位置,您不能--必须替换整个文件。†
您可以将每一行(包括更改)打印到另一个文件中,然后将其复制到另一个文件中。许多工具都是这样工作的。或者,您可以读取所有行,根据需要进行更改,然后覆盖该文件
my $qfn = "d00.dat";
my $file;
{
open(my $fh, '<', $qfn)
or die("Can't open \"$qfn\": $!\n");
local $/;
$file = <$fh>;
}
$file =~ s/d01/d02/g;
{
open(my $fh, '>', $qfn)
or die("Can't create \"$qfn\": $!\n");
print($fh $file);
}
my $filename = "d00.dat";
open(my $fh, '<', $filename) || die "file could not open $! \n";
my @new_lines = map { s/d01/d02/g; $_ } <$fh>;
close $fh;
open(my $fh_out, '>', $filename) || die "file could not open $! \n";
print $fh_out $_ for @new_lines;
close $fh_out;
其中,我删除了参数并更改为或,并将$filename
添加到错误消息中。我还在regex中使用/r
修饰符(“无损替换”),返回更改后的字符串——与映射
所需的完全相同,因此现在我们不需要在块的末尾使用单独的$\ucode>
问题中出现的die
消息末尾的换行符有一个微妙的后果:它会抑制有关发出die
的行号的信息。虽然有时需要这样做,但在大多数情况下并非如此,我们当然希望看到失败调用的行号!因此我删除了它die
消息中的附加换行符
† 一个文件是一个字节序列。因此,如果我们想用yes
替换nope
…最后一个字符e
会发生什么情况,一旦我们替换了前三个字符?我们必须移动文件的其余部分,跟随原始nope
,以覆盖e
,然后再跟随yes
需要覆盖文件的其余部分,实际上只替换整个文件要容易得多
如果我们想用是的
替换否
…那么,现在是四对四,我们实际上可以覆盖这四个字符。然而,这种情况很少发生,而且更复杂
当问题要求将d01
替换为d02
时,我认为这是一个示例,但实际上字符串的长度通常不相同。即使它们是…替换文件更容易、更安全,并且很可能不会注意到效率损失。您只是在读取文件并打印重播ced字符串,它将如何反映在文件中?您应该在perl
中使用sed
和system
命令来实现这一点。@AbhiNickz没有必要求助于sed,perl可以“就地”完成修改很好。是的,但Enric只是编写了读取文件的代码,所以我建议了另一种修改文件的方法,Tie::file永远不是*答案!(*好,差不多)…而Tie::Fighter总是*答案!(*好,差不多);-)