输出格式-如何在Perl中以列形式打印数据



我有一个以行为单位打印数组内容的程序。我想让它在一个列中打印每个数组。

这是代码:

#!/usr/local/bin/perl
use strict;
use warnings;
my @M_array;
my @F_array;
open (my $input, "<", 'ssbn1898.txt');
while ( <$input> ) {
    chomp;
    my ( $name, $id ) = split ( /,/ ); 
    if ( $id eq "M" ) {
        push ( @M_array, $name );
    }
    else {
        push ( @F_array, $name ); 
    }
}
close ( $input );
print "M: @M_array n"; 
print "F: @F_array n";

这是可能的还是我在尝试做一些不能做的事情?

所需格式:

M      F 
Namem1 Namef1 
Namem2 Namef2 

您可以使用join函数在数据之间添加任何分隔符,下面的示例以制表符分隔数组中的数据:

...
use List::MoreUtils qw/pairwise/;
my $separator = "t";
print join($separator, qw(M F)), "n";
print join(
   "n", 
   pairwise { ( $a // '') . $separator . ( $b // '') } @M_array, @F_array
), "n";
...

我认为,您应该使用Perl格式。请查看Perl文档。您可能希望在您的情况下使用@*格式字段。

我扩展了你的代码,以便在

末尾打印所需的输出
use strict;
use warnings;
my @M_array;
my @F_array;
open (my $input, "<", 'ssbn1898.txt');
while ( <$input> ) {
    chomp;
    my ( $name, $id ) = split ( /,/ ); 
    if ( $id eq "M" ) {
        push ( @M_array, $name );
    }
    else {
        push ( @F_array, $name ); 
    }
}
close ( $input );
unshift @M_array, 'M';
unshift @F_array, 'F';
my $namem; 
my $namef;
my $max = 0;
$max = (length($_) gt $max  ? length($_) : $max) for @M_array;
my $w = '@' . '<' x $max;
eval "
format STDOUT = 
$w @*
$namem, $namef 
.
";
while ( @M_array or @F_array) {
    $namem = shift @M_array || '';
    $namef = shift @F_array || '';
    write;
}

join可能是最简单的方法,tabs将很好地对齐您的列。

join ( "t", @array ),
或者,perl允许通过(s)printf: 进行格式化
printf ( "%-10s %-10s", "first", "second" );

或更详细的"格式"

考虑到你要做的是把你的两个数组放到列中:

#!/usr/local/bin/perl
use strict;
use warnings;
my $format = "%-10st%-10sn";
my @M_array = qw ( M1 M2 M3 M4 M5 );
my @F_array = qw ( F1 F2 F3 );
my $maxrows = $#M_array > $#F_array ?  $#M_array : $#F_array; 
printf ( $format, "M", "F" );
for my $rownum ( 0..$maxrows ) { 
    printf ( $format, $M_array[$rownum] // '', $F_array[$rownum] // '' );
}

这将打印标题行,然后循环遍历数组,每次打印一行。//是一个条件操作,用于测试是否定义了某些内容。不过,它只在较新的perl中可用*。在旧版本中,||可以做到这一点——它的几乎与相同,但处理''0的方式略有不同。

* Perl 5.10以后,所以是相当安全的,但值得一提的是,因为一些系统仍然在Perl 5.8上摇摆。

您可以使用sprintf函数格式化输出,但是还有一些问题需要解决:如果数组的条目计数不相同怎么办?为此,您需要一个占位符。一栏要装多少字母?它应该如何对齐?一些用于说明的代码:

#!/usr/bin/perl
use strict;
use warnings;
my @m = (1, 2, 3);
my @f = (11, 22, 33, 44);
# calculate how many rows to display
my $max = @m;
if (@m < @f) {
    $max = @f;
}
# placeholder for missing data
my $none = '-';
# formatting 20 chars per column, left aligned
my $fmt = "%-20s%-20sn";
# print header
print sprintf($fmt, "M", "F");
# print data rows
foreach my $i (0..$max-1) {
    print sprintf($fmt, ($m[$i] or $none), ($f[$i] or $none));
}

如果您对更复杂的格式(例如居中对齐的文本)感兴趣,您应该切换到Perl为报表生成提供的特殊格式功能。

借用自@HunterMcMillen

use strict;
use warnings;
use feature "say";
local $, = "t";   # separator when printing list
my $i = (@F_array > @M_array) ? $#F_array : $#M_array;
say qw(M F);
say $M_array[$i] //"", $F_array[$i] //"" for 0 .. $i;

我猜Text::Table是perl发行版所需的模块(只需要安装)。查看下面的文档-

document of Text::Table

您需要将内容作为数组传递给add()方法,它将为您创造奇迹。

相关内容

  • 没有找到相关文章

最新更新