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.

但我得到的是空文件。

谢谢你们,我能够使用变量来解决问题,我只是将正则表达式作为变量,它工作正常。

4

1 回答 1

3

当您打开文件以使用该模式写入时>,它会自动截断为零长度。

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

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

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开关所做的,它允许您逐行编辑任意长的文件(只要您有足够的磁盘空间来存储副本)。不幸的是,在您的情况下,使用此方法匹配文件中特定字符串的最后一次出现会有点棘手。

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

于 2012-12-24T20:43:14.103 回答