English 中文(简体)
How can I format columns without using Perl s format?
原标题:

Often in Perl I want to print out column/row data, say, from a hash.

This is simple:

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

However, if the key happens to have a varying length, then the formatting just looks very jagged. I ve investigated format, and it s typically too heavyweight for what I m looking for, which is a simple column-row aligning pretty-printer.

最佳回答

I think you ll find printf useful. Here is a small example:

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

Long values are not truncated, and you can change text alignment inside the block:

  • %10s - means string type of length 10 (left aligned)
  • %-10s - means string type of length 10 (right aligned)

A full list of formats is on the sprintf man page.

问题回答

Check out the x operator (documented at perldoc perlop), useful for simple formatting tasks that involve padding fields to a specific length:

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

You can also use sprintf or printf (perldoc -f sprintf, perldoc -f printf) (with these you can also pad with zeros in numbers):

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

The robust solution requires two passes: one to determine the length of the longest key, the other to print the output:

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

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

If you know the upper limit of the key lengths ahead of time, you can avoid the first loop.

If you want a heavy-duty solution, there are modules like Text::Table.

It is probably not an optimal solution, but you ll need to find your maximum key and maximum value lengths, and then pass them to either sprintf() or pack().

Or you could use static maximum lengths if your data source has "reasonable" constraints (for example, column length limits in a database, etc.)

I know you said format might be too heavy-weight, but it might actually be less complex. Try something like this:

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

  write;
}




相关问题
Why does my chdir to a filehandle not work in Perl?

When I try a "chdir" with a filehandle as argument, "chdir" returns 0 and a pwd returns still the same directory. Should that be so? I tried this, because in the documentation to chdir I found: "...

How do I use GetOptions to get the default argument?

I ve read the doc for GetOptions but I can t seem to find what I need... (maybe I am blind) What I want to do is to parse command line like this myperlscript.pl -mode [sth] [inputfile] I can use ...

Object-Oriented Perl constructor syntax and named parameters

I m a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot. package Foo; #In Perl, the constructor is just a subroutine called new. sub new { #I ...

Where can I find object-oriented Perl tutorials? [closed]

A Google search yields a number of results - but which ones are the best? The Perl site appears to contain two - perlboot and perltoot. I m reading these now, but what else is out there? Note: I ve ...

热门标签