如何在不使用Perl格式的情况下格式化列?

时间:2009-11-13 17:29:20

标签: perl formatting

通常在Perl中,我想从散列中打印出列/行数据。

这很简单:

foreach my $k(keys %h)
{
  print $k, "\t", $h{$k}, "\n";
}

但是,如果密钥恰好具有变化长度,那么格式化只会看起来非常锯齿状。我已经调查了format,它通常对我正在寻找的东西来说太重了,这是一个“简单”的列行对齐漂亮的打印机。

6 个答案:

答案 0 :(得分:16)

我认为你会发现printf有用。这是一个小例子:

printf("%10s\t%10s\n", $k, $h{$k});
## prints "         key\t         value\n"
## prints "  longer_key\t  longer_value\n"

不会截断长值,您可以在块中更改文本对齐:

  • %10s - 表示长度为10(左对齐)
  • 的字符串类型
  • %-10s - 表示长度为10的字符串类型(右对齐)

完整的格式列表位于sprintf man page

答案 1 :(得分:7)

查看x运算符(记录在perldoc perlop),对于涉及填充字段到特定长度的简单格式化任务非常有用:

while ((my $key, $value) = each %h)
{
    print $key . (" " x (20 - length $key)) . $value, "\n";
}

您还可以使用sprintfprintfperldoc -f sprintfperldoc -f printf)(这些也可以在数字中用零填充):

while ((my $key, $value) = each %h)
{
    printf("%20s %20s\n", $key, $value);
}

答案 2 :(得分:6)

强大的解决方案需要两次通过:一次确定最长键的长度,另一次打印输出:

my $l = 0;
foreach my $key (keys %hash) {
    $l = length($key) if length($key) > $l;
}

foreach my $key (keys %hash) {
    printf "%-${l}s  %s\n", $key, $hash{$key};
}

如果您提前知道了密钥长度的上限,则可以避免第一次循环。

答案 3 :(得分:5)

如果您需要重型解决方案,可以使用Text::Table等模块。

答案 4 :(得分:3)

可能不是最佳解决方案,但您需要找到最大密钥和最大值长度,然后将它们传递给sprintf或pack。或者,如果数据源具有“合理”约束(例如,数据库中的列长度限制等),则可以使用静态最大长度

答案 5 :(得分:1)

我知道你说格式可能太重了,但实际上可能不那么复杂。尝试这样的事情:

foreach my $k(keys %h) {
  format =
  Key:  @<<<<<<<<<<<<<<<< Value:  @>>>>>>>>>>>>>>>>>
  $k,                     $h{$k}  
  .

  write;
}

希望这会有所帮助!!

相关问题