到目前为止我已经做到了这一点,但它仍然不起作用。
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.
但是我得到的是空文件。
谢谢你们,我能够使用变量解决问题,以替换我只是将正则表达式作为变量,并且效果很好。
当您打开文件以使用
>
模式进行写入时,它会自动截断为零长度。
可以使用 +<
模式打开一个文件同时进行读取和写入,而不截断它,但实际上修改这样的文件有点棘手,因为它需要
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 接口),所以你基本上必须以相反的顺序将输出行写入临时文件,然后执行第二遍以正确的顺序将它们复制回原始文件。这应该是可能的,但有点复杂。)