Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用perl修改文件中的字符串_Perl - Fatal编程技术网

用perl修改文件中的字符串

用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

我有一个文件,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 "$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总是*答案!(*好,差不多);-)