我想打开一个文件并替换perl中字符串的最后出现模式

问题描述 投票:0回答:1

到目前为止我已经做到了这一点,但它仍然不起作用。

open (GOOD_FILE,"<$pre.XXX.XXX$post") or die "Cannot open XXX";

# temporarily undefine the input line separator to read the entire file at once:
my $text = do { local $/; <GOOD_FILE> };
close GOOD_FILE or die $!;
#File name to replace XXXX.XXXXX.XXXX.XXXX.CCCC where last CCCC can be     anything 
$text =~ s/^(.*\n)?XXXX\.XXXX\.XXXX\.[^\n]*/$1myname/s;

open (GOOD_FILE,"<$pre.XXXX.XXXX$post") or die "Cannot open XXXX";
print GOOD_FILE $text;
close GOOD_FILE or die $!;

输入文件如下所示:

I am tester testing
I am still learning.
XXXX.XXXX.XXXX.XXXX.CCCC
I am tester.
XXXX.XXXX.XXXX.XXXX.PPPP

它应该产生以下输出:

I am tester testing
I am still learning.
XXXX.XXXX.XXXX.XXXX.CCCC
I am tester.
myname.

但是我得到的是空文件。

谢谢你们,我能够使用变量解决问题,以替换我只是将正则表达式作为变量,并且效果很好。

string perl pattern-matching
1个回答
3
投票

当您打开文件以使用

>
模式进行写入时,它会自动截断为零长度。

可以使用 +< 模式打开一个文件同时进行读取和写入,而不截断它,但实际上修改这样的文件有点棘手,因为它需要

seeking
相反,有两种简单的方法可以实现您想要的目标。如果您知道文件总是相对较短,您可以将其读入内存,修改它并写回:

my $filename = 'filename.txt'; open my $in, '<', $filename or die $!; # temporarily undefine the input line separator to read the entire file at once: my $text = do { local $/; <$in> }; close $in or die $!; $text =~ s/^(.*\n)?MY\.FILE\.NAME\.[^\n]*/$1myname/s; open my $out, '>', $filename or die $!; print $out $text; close $out or die $!;

对于大文件,另一种解决方案是将输出写入临时文件,然后在完成后将临时文件移动到原始文件上。这或多或少是 
perl 的

-i 开关

 的作用,它允许您逐行编辑任意长的文件(只要您有足够的磁盘空间来存储副本,无论如何)。不幸的是,在您的情况下,使用此方法匹配文件中特定字符串的 
last 出现会变得有点棘手。 (我想你

可以

使用File::ReadBackwards,但不幸的是没有File::WriteBackwards模块与之配合(并且由于操作系统文件的限制,我很难编写一个模块) /O 接口),所以你基本上必须以相反的顺序将输出行写入临时文件,然后执行第二遍以正确的顺序将它们复制回原始文件。这应该是可能的,但有点复杂。)

© www.soinside.com 2019 - 2024. All rights reserved.