Perl格式化以分别显示2个循环

Perl格式化以分别显示2个循环,perl,format,Perl,Format,我有下面的散列 my $hash = {1 => {'a'=>'a1','b'=>'b1', 'c'=>'c1', 'd'=>'d1'}, 2 => {'a'=>'e1','b'=>'f1', 'c'=>'g1', 'd'=>'h1'}, 3 => {'a'=>'i1','b'=>'j1','c'=>'k1', 'd'=>'l1'}, 4 => {'a'=>'m1','b

我有下面的散列

my $hash = {1 => {'a'=>'a1','b'=>'b1', 'c'=>'c1', 'd'=>'d1'},
    2 => {'a'=>'e1','b'=>'f1', 'c'=>'g1', 'd'=>'h1'},
    3 => {'a'=>'i1','b'=>'j1','c'=>'k1', 'd'=>'l1'},
    4 => {'a'=>'m1','b'=>'n1','c'=>'o1','d'=>'p1'}};
我想以perl格式的方式显示上面的散列。散列的散列本质上是动态的,所以我们以后也可以有额外的键

我使用下面的代码将哈希生成为正确的格式

use strict;
my $hash = {1 => {'a'=>'a1','b'=>'b1', 'c'=>'c1', 'd'=>'d1'},
        2 => {'a'=>'e1','b'=>'f1', 'c'=>'g1', 'd'=>'h1'},
        3 => {'a'=>'i1','b'=>'j1','c'=>'k1', 'd'=>'l1'},
        4 => {'a'=>'m1','b'=>'n1','c'=>'o1','d'=>'p1'}};

my @a = qw(1 2);
my @b = qw(3 4);
&displayreport($hash, \@a);
print "new display\n\n";
&displayreport($hash, \@b);
my($i,$j,$k,$l); 
format STDOUT_TOP =
 A  B   C   D
 -- --  --  --
.
format OUTPUT=
@<< @<< @<< @<<
$i,$j,$k,$l
.

sub displayreport{
    my ($x, $y) = @_;

    $~ = "STDOUT_TOP";
    write;
    foreach(@$y) {
        $i = $hash->{$_}->{a};
        $j = $hash->{$_}->{b};
        $k = $hash->{$_}->{c};
        $l = $hash->{$_}->{d};
        $~ = "OUTPUT";
        write();
    }
}
其中,重复第一种情况下的标题

我需要输出为

 A      B       C       D
 --     --      --      --
a1      b1      c1      d1
e1      f1      g1      h1

new display

 A      B       C       D
 --     --      --      --
i1      j1      k1      l1
m1      n1      o1      p1

我做错了什么。请协助。

STDOUT\u-TOP
重命名为
STDOUT\u-TOPX
,即可使用。但是我不知道为什么。

的后缀有
\u TOP
作为

通过打开新文件句柄的输出,并使用
$^
变量设置
$FORMAT\u TOP\u NAME
,可以更明确地利用这一点

这表现在以下方面:

use strict;
use warnings;

my $hash = {
    1 => { 'a' => 'a1', 'b' => 'b1', 'c' => 'c1', 'd' => 'd1' },
    2 => { 'a' => 'e1', 'b' => 'f1', 'c' => 'g1', 'd' => 'h1' },
    3 => { 'a' => 'i1', 'b' => 'j1', 'c' => 'k1', 'd' => 'l1' },
    4 => { 'a' => 'm1', 'b' => 'n1', 'c' => 'o1', 'd' => 'p1' },
};

displayreport( $hash, [1,2] );

print "\nnew display\n";
displayreport( $hash, [3,4] );

format OUTPUT_TOP =
 A   B   C   D
 --  --  --  --
.

my ( $i, $j, $k, $l );
format OUTPUT=
 @<< @<< @<< @<<
$i,$j,$k,$l
.

sub displayreport {
    my ( $hash, $keys ) = @_;

    open my $fh, '>', \my $output or die "Can't open: $!";
    my $ofh = select($fh);

    $^ = "OUTPUT_TOP";
    $~ = "OUTPUT";

    foreach (@$keys) {
        ($i, $j, $k, $l) = @{$hash->{$_}}{qw(a b c d)};
        write();
    }

    select($ofh);
    close $fh;
    print $output;
}
两种选择 首先,如果您真的想使用格式,我建议您使用更现代的格式

第二,我强烈建议对这类基本格式和跳过格式一起使用更简单的和:

displayreport( $hash, [1,2] );

print "\nnew display\n";
displayreport( $hash, [3,4] );

sub displayreport {
    my ( $hash, $keys ) = @_;

    my $fmt = " %3s %3s %3s %3s\n";

    printf $fmt, qw(A B C D);
    printf $fmt, qw(-- -- -- --);

    foreach (@$keys) {
        printf $fmt, @{$hash->{$_}}{qw(a b c d)};
    }
}

输出与前面的脚本相同。

\u TOP
命名格式是特殊的=>
 A   B   C   D
 --  --  --  --
 a1  b1  c1  d1
 e1  f1  g1  h1

new display
 A   B   C   D
 --  --  --  --
 i1  j1  k1  l1
 m1  n1  o1  p1
displayreport( $hash, [1,2] );

print "\nnew display\n";
displayreport( $hash, [3,4] );

sub displayreport {
    my ( $hash, $keys ) = @_;

    my $fmt = " %3s %3s %3s %3s\n";

    printf $fmt, qw(A B C D);
    printf $fmt, qw(-- -- -- --);

    foreach (@$keys) {
        printf $fmt, @{$hash->{$_}}{qw(a b c d)};
    }
}