如何同时将内容打印到两个文件中?

7
我有些困难让这行代码正常工作:

for my $fh (FH1, FH2, FH3) { print $fh "whatever\n" }

我在perldoc上找到了相关信息,但是对我没有用。

我目前的代码如下:

my $archive_dir = '/some/cheesy/dir/';
my ($stat_file,$stat_file2) = ($archive_dir."file1.txt",$archive_dir."file2.txt");
my ($fh1,$fh2);

for my $fh (fh1, fh2) { print $fh "whatever\n"; }

由于我正在使用 strict,所以在 (fh1, fh2) 部分出现了“裸字”错误。我还注意到示例中缺少一个 ;,因此我猜测可能还有其他错误。

如何正确地将内容同时输出到两个文件?


1
尝试使用 for my $fh ( \*FH1, \*FH2, \*FH3) { ... } 或者 for my $fh ( \*{FH1}{IO}, \*{FH2}{IO}, \*{FH3]{IO}) { ... } - Brad Gilbert
perldoc -f filenhandle indirectly 使用文件句柄间接操作 - Brad Gilbert
5个回答

17

你还没有打开这些文件。

my ($fh1,$fh2);
open($fh1, ">", $stat_file) or die "Couldn't open $stat_file: $!";
open($fh2, ">", $stat_file2) or die "Couldn't open $stat_file2: $!";

for my $fh ($fh1, $fh2) { print $fh "whatever\n"; }

请注意,我并没有使用裸字。在旧时代,你可能会这样写:

open(FH1, ">$stat_file");
...
for my $fh (FH1, FH2) { print $fh "whatever\n"; }

但现代方法是前者。


2
仅供记录,裸字错误是因为 OP 使用了 fh1fh2 而不是 $fh1$fh2 - 并且可能会在从使用裸字的示例复制时将它们打开为 open(fh1, ...) - Cascabel
我没有打开文件...这种愚蠢何时才能结束? 我还需要将 ($fh1,$fh2) 部分更正,所以谢谢++ - CheeseConQueso
我相信你的意思是 for my $fh ( \*FH1, \*FH2 ) { ... } 或者 for my $fh ( \*{FH1}{IO}, \*{FH2}{IO} ) { ... } - Brad Gilbert
@Brian - 在死亡威胁部分,$statfile$statfile2 应分别改为 $stat_file$stat_file2 - CheeseConQueso
@CheeseConQueso 哎呀 - 对不起。而 Brad ... 不,我没有。 - Brian Roach
@Brian - 如果在错误消息中包含$!以指示为什么无法打开文件,那将是一种改进。 - Sherm Pendley

7
我建议使用IO::Tee来解决问题。
use strict;
use warnings;
use autodie; # open will now die on failure
use IO::Tee;

open my $fh1, '>', 'file1';
open FH2, '>', 'file2';

my $both = IO::Tee->new( $fh1, \*FH2 );

print {$both} 'This is file number ';

print {$fh1} 'one';
print FH2    'two';

print {$both} "\n";
print {$both} "foobar\n";

$both->close;

运行以上程序会得到以下结果:

file1

这是第一个文件
foobar

file2

这是第二个文件
foobar
我建议阅读整个perldoc文件以获取更高级的用法。

4

看起来大致正确,只是在Perl中使用裸字作为文件句柄曾经很常见,但现在建议使用普通标量。

所以确保您实际上已经打开了文件,然后将 (fh1, fh2) 部分替换为实际的文件句柄(应该是 ($fh1,$fh2) 或其他内容)


0

你需要先打开文件才能获得有效的文件句柄

open (MYFILEA, $stat_file);
open (MYFILEB, $stat_file2);
for my $fh ( \*MYFILEA, \*MYFILEB ) { print $fh "whatever\n" } 
close (MYFILEA);
close (MYFILEB); 

1
你应该使用三个参数的 open。 - Nikhil Jain
1
我相信你指的是 for my $fh ( \*MYFILEA, \*MYFILEB ) { print $fh "whatever\n" } - Brad Gilbert
假设它正在严格模式下运行,这在问题中已经说明。(我应该在我的评论中添加这个。) - Brad Gilbert

0

基于Brian的答案的另一个版本:

open(my $fh1, ">", $stat_file) or die "Couldn't open $stat_file!";
open(my $fh2, ">", $stat_file2) or die "Couldn't open $stat_file2!";
for ($fh1, $fh2) { print $_ "whatever\n"; }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接