如何扫描文件句柄两次以根据其内容复制它?

How can I scan a filehandle twice to copy it based on its contents?

我的整个 perl 脚本正在尝试按如下方式运行:

#!/usr/bin/perl
use warnings;
use strict;

my $src = 'D:\Scripts\sample.c';
my $fileName;

# open source file for reading
open(SRC,'<',$src) or die $!;

while(my $row = <SRC>){
    if ($row =~ /([0-9]{2}\.[0-9]{2}\.[0-9]{3}\.[a-z,0-9]{2}|[0-9]{2}\.[0-9]{2}\.[0-9]{3}\.[a-z,0-9]{3})/){
        $fileName = ;
    }
}

my $des = "D:\Scripts\" . $fileName . ".txt";

# open destination file for writing
open(DES,'>',$des) or die $!;

print("copying content from $src to $des\n");

while(my $row = <SRC>){
    if ($row =~ /(\/\*.*abcd.[\s\S]*?\*\/)/){
        print DES ;
    }
}

# always close the filehandles
close(SRC);

close(DES);
print "File content copied successfully!\n";

我是 运行 在 Windows 10 命令行中使用 Perl 5.32.1。我的问题是我没有将任何内容写入目标文件。文件已创建,但没有内容写入其中。当我改变时:

print DES ; -> print "\n";

我也没有从命令行 window 中得到任何内容。当我将整个第二个 if 语句移动到嵌套在第一个 if 语句之后的第一个 while 循环下面时,我将输出输出到命令行。但是我不能在那里保留第二个 if 语句,因为我希望它写入目标文件。

由于第一次读取 $src 文件,因此 SRC 文件句柄到达文件末尾。因此,当您尝试再次读取该文件时,该文件句柄上没有任何可读取的内容(它不会告诉)。

第一次读取完成后,将文件句柄重新定位到文件开头

seek SRC, 0, 0;

有很好的符号常量可以与 seek, see Fcntl

一起使用

另一种选择是关闭并再次打开文件。 (或者甚至只是 re-open 相同的文件句柄,在这种情况下它首先被关闭。)


注意:使用词法文件句柄比使用 typeglobs 更好,例如

open my $src_fh, '<', $src_file  or die $!;

查看评论 in perldata, and search SO posts (here is one 例如)。

我会稍微修改一下问题。与其读取文件两次,不如读取一次。写入名称不重要的临时文件。一路上,发现最终的文件名。完成后,重命名临时文件。