【问题标题】:Perl file regex doesn't replace textPerl 文件正则表达式不会替换文本
【发布时间】:2014-03-07 03:29:36
【问题描述】:

如果这不是重复的,我会感到惊讶,但我似乎无法在任何地方找到解决此问题的方法。我正在尝试用另一个字符串替换文件中给定字符串的所有实例。我遇到的问题是脚本打印了替换的版本但保留了原始版本。我对 perl 很陌生,所以我确信这是一个微不足道的问题,我错过了一些东西

代码:

my $count;
my $fname = file_entered_by_user;
open (my $fhandle, '+<', $fname) or die "Could not open '$fname' for read: $!";

for (<$fhandle>) {
    $count += s/($item_old)/$item_new/g;
    print $fhandle $_;
}   
print "Replaced $count occurence(s) of '$item_old' with '$item_new'\n";
close $fhandle;

原始文件:

This is test my test file where
I test the string perl script with test
strings. The word test appears alot in this file
because it is a test file.

结果文件:

This is test my test file where
I test the string perl script with test
strings. The word test appears alot in this file
because it is a test file
This is sample my sample file where
I sample the string perl script with sample
strings. The word sample appears alot in this file
because it is a sample file.

预期结果文件:

This is sample my sample file where
I sample the string perl script with sample
strings. The word sample appears alot in this file
because it is a sample file.

其他信息:

  • $item_old$item_new 由用户提供。在给出的示例中,我将test 替换为sample
  • 我对这个问题的单一解决方案不感兴趣。它将与更大的程序集成,因此可以从终端运行的单行解决方案不会有太大帮助。

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    问题是你使用+&lt; 模式,认为它会做你认为它做的事情。您正在做的是首先读取文件中的所有行,将文件句柄位置放在文件末尾,然后打印后面的行。

    这一行

    for (<$fhandle>) {
    

    读取文件句柄的所有行并将它们放入一个列表中,然后循环在该列表上进行迭代。它会一直读取到eof,然后才会添加您的更改。

    如果您想让您的解决方案发挥作用,您必须在打印前回退文件句柄。 IE。

    seek($fhandle, 0, 0);
    

    在我看来,虽然这些解决方案不是很好。尤其是当有内置功能来处理这种事情时:

    perl -pi.bak -we 's/$item_old/$item_new/g' yourfile.txt
    

    带有-p 标志的-i 标志使您的代码应用于文本文件,并相应地更改它,保存扩展名为.bak 的副本。当然,您必须提供要进行的替换,因为您没有提供。

    编辑:我刚刚看到您不想要单线。好吧,要做到这一点,您只需要打开正确的文件句柄并将更改的文件复制到旧文件上。所以,基本上:

    use strict;
    use warnings;
    use File::Copy;
    
    open my $old, "<", $oldfile or die $!;
    open my $new, ">", $newfile or die $!;
    
    while (<$old>) {
        s/$item_old/$item_new/g
        print $new $_;
    }
    copy $newfile, $oldfile or die $!;
    

    大多数时候,考虑到处理文件副本的容易程度,使用允许在同一个文件句柄上读取和写入的模式使用起来比它的价值要复杂得多。

    【讨论】:

      猜你喜欢
      • 2014-03-11
      • 1970-01-01
      • 1970-01-01
      • 2013-01-12
      • 2017-10-18
      • 2017-01-21
      • 2019-11-29
      相关资源
      最近更新 更多