Dr.Avocado has asked for the wisdom of the Perl Monks concerning the following question:

Dear Perl experts,
I need a better way to display some information.
@names contains NameA, NameB, NameC, and NameD.
@ages contains 353, 32, 2356, and 75.
@sizes contains 44, 212, 32, and 328.
@scores contain 900, 128, 99, and 1000.
If the first element of each array go with each other, as do the second, third, and so on, is there a way to print an output like:
====================================================================== +============== Name Age Size + Score ====================================================================== +============== NameA 353 44 + 900 NameBCG 32 212 + 128 NameC 2356 32 + 99 NameD 75 328 + 1000 ====================================================================== +==============
I know how to do this for the most part; it's just the alignment of values that I'm not familiar how to do ( I want to make the rightmost character in each column line up). Since the names and values may be of different lengths, I run into difficulties trying to make organized outputs like this. Is there a way to print an output in this fashion?
Thanks for any help.

Replies are listed 'Best First'.
Re: Aligning Text
by FunkyMonk (Bishop) on Aug 13, 2007 at 16:47 UTC
    There's a few different ways of achieving this, but I'd use printf.

    printf( "%-10s", "hello" );

    will print "hello", left justified in a field 10 chars wide.

    printf( "%10d", 777);

    will print 777, right justified in a field also 10 chars wide.

Re: Aligning Text
by duff (Parson) on Aug 13, 2007 at 17:20 UTC
Re: Aligning Text
by toolic (Bishop) on Aug 13, 2007 at 16:50 UTC
    For printing out simple tables of data, I find Text::Table useful.
Re: Aligning Text
by thezip (Vicar) on Aug 13, 2007 at 16:52 UTC

    printf is your friend. Use something like this to produce the columnar formatted output you need:

    printf "%-10s %4d %3d %4d\n", $name, $age. $size, $score;

    FMTYEWTKA sprintf

    Update: Adjusted specs a bit


    Where do you want *them* to go today?
Re: Aligning Text
by GrandFather (Saint) on Aug 13, 2007 at 21:42 UTC

    If you want to size the table according to maximum data widths then the * is worth knowing about in a printf format string:

    use strict; use warnings; use List::Util qw(min max); my @names = qw(NameA NameB NameC NameD); my @ages = (353, 32, 2356, 75); my @sizes = (44, 212, 32, 328); my @scores = (900, 128, 99, 1000); my $nameWidth = max (map length, @names, 'name') + 3; my $ageWidth = max (map length, @sizes, 'Age') + 3; my $sizeWidth = max (map length, @sizes, 'Size') + 3; my $scoreWidth = max (map length, @scores, 'Score') + 3; print '-' x ($nameWidth + $ageWidth + $sizeWidth + $scoreWidth), "\n"; printf "%-*s%*s%*s%*s\n", $nameWidth, "Name", $ageWidth, "Age", $sizeWidth, "Size", $scoreWidth, "Score"; print '-' x ($nameWidth + $ageWidth + $sizeWidth + $scoreWidth), "\n"; for my $index (0 .. $#names) { printf "%-*s%*s%*s%*s\n", $nameWidth, $names[$index], $ageWidth, $ages[$index], $sizeWidth, $sizes[$index], $scoreWidth, $scores[$index]; }

    Prints:

    ----------------------------- Name Age Size Score ----------------------------- NameA 353 44 900 NameB 32 212 128 NameC 2356 32 99 NameD 75 328 1000

    DWIM is Perl's answer to Gödel
Re: Aligning Text
by dwm042 (Priest) on Aug 13, 2007 at 19:22 UTC
    If you're wanting the lineup in your example, this code works:

    #!/bin/perl use warnings; use strict; package main; my @names = ('NameA', 'NameB', 'NameC','NameD' ); my @ages = (353, 32, 2356, 75); my @sizes = (44, 212, 32, 328); my @scores = (900, 128, 99, 1000); print "======================================="; print "=============================================\n"; print " Name Age "; print " Size Score\n"; print "======================================="; print "=============================================\n"; for ( my $i = 0; $i < scalar @names; $i++ ) { printf "%5s %4d ", $names[$i], $ages[$i]; printf " %4d %4d\n", $sizes[$i], $scores[$i]; }
    giving this output:

    C:\Code>perl table.pl ====================================================================== +============== Name Age Size + Score ====================================================================== +============== NameA 353 44 900 NameB 32 212 128 NameC 2356 32 99 NameD 75 328 1000
    And the code does show how you can align your output using printf. But you may have variable length @names and @ages and such, and this kind of hard coded solution doesn't work well with something you would use over and over again. A smarter solution would save you from using many many cut-and-paste variants of this over and over again.