Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Formatting Output

by jwalker1960 (Initiate)
on Oct 11, 2012 at 17:27 UTC ( #998493=perlquestion: print w/ replies, xml ) Need Help??
jwalker1960 has asked for the wisdom of the Perl Monks concerning the following question:

I am using Text::CSV to read in data from a CSV file. this works well enough, but the output looks less than pretty.

Here is the perl code I'm using:

#!/usr/bin/perl use strict; use warnings; use Text::CSV; my $file = 'test.csv'; my $csv = Text::CSV->new(); open (CSV, "<", $file) or die $!; while (<CSV>) { if ($csv->parse($_)) { my @columns = $csv->fields(); print "@columns\n"; } else { my $err = $csv->error_input; print "Failed to parse line: $err"; } } close CSV;

Here is a sample of data from the CSV file:

Account,Login Name,Password,Web Site,Comments Google Docs,george123,F0oB@r,http://www.google.com/docs,The GoodleDocs + site Amazon,george123,fo0bA7,http://www.amazon.com,The Amazone Kindle site Apple,george123,mM_B39Aa,https://www.apple.com/accountmanagement,My Ap +ple account

When I use my perl script to parse this, here is what I get:

Account Login Name Password Web Site Comments Google Docs george123 F0oB@r http://www.google.com/docs The GoodleDocs + site Amazon george123 fo0bA7 http://www.amazon.com The Amazone Kindle site Apple george123 mM_B39Aa https://www.apple.com/accountmanagement My Ap +ple account

As you can see, the columns don't line up well to make it readable.

Here is what I'd like it to look like:

Account 	Login Name 	Password	Web Site 				Comments
Google Docs 	george123 	F0oB@r 		http://www.google.com/docs 		The GoodleDocs site
Amazon 		george123 	fo0bA7 		http://www.amazon.com/kindle 		The Amazone Kindle site
Apple 		george123 	mM_B39Aa	https://www.apple.com/accountmanagement My Apple account

I haven't been able to figure out how to get it formatted all purdy like it is above and would appreciate any help you could give

Comment on Formatting Output
Select or Download Code
Re: Formatting Output
by toolic (Chancellor) on Oct 11, 2012 at 17:36 UTC
    If you know ahead of time how wide each column is, use printf. If you want your columns to be auto-scaled for you, you can use a module like Text::Table.
      I was just about to suggest Text::Table, too. I love how you can have columns aligned by arbitrary characters (e.g., the decimal in a number). The only drawback is if you want to open your output in Excel or something, the columns don't get split as easily as if it were tab-delimited, etc.

        If you're going to be using Excel, why do you care what the bare output looks like?

Re: Formatting Output
by kcott (Abbot) on Oct 12, 2012 at 09:04 UTC

    G'day jwalker1960,

    Welcome to the monastery.

    Here's another way to do it (using pack):

    #!/usr/bin/env perl use strict; use warnings; print pack 'A12A11A9A40A*' => split /,/ for <DATA>; __DATA__ Account,Login Name,Password,Web Site,Comments Google Docs,george123,F0oB@r,http://www.google.com/docs,The GoodleDocs + site Amazon,george123,fo0bA7,http://www.amazon.com,The Amazone Kindle site Apple,george123,mM_B39Aa,https://www.apple.com/accountmanagement,My Ap +ple account

    Output:

    $ pm_pack_fmt_txt.pl Account Login Name Password Web Site + Comments Google Docs george123 F0oB@r http://www.google.com/docs + The GoodleDocs site Amazon george123 fo0bA7 http://www.amazon.com + The Amazone Kindle site Apple george123 mM_B39Aa https://www.apple.com/accountmanagemen +t My Apple account

    -- Ken

      Thanks Ken! That worked beautifully!

        If you liked the pack solution, here's a more versatile version (with some additional test data):

        #!/usr/bin/env perl use strict; use warnings; my (@data, @max); while (<DATA>) { push @data => [ split /,/ ]; @max = map { my $len = length $data[$#data][$_]; ( $max[$_] ||= 0 ) >= $len ? $max[$_] : $len; } 0 .. $#{$data[$#data]} - 1; } my $template = 'A' . join(A => ( map { $_ + 1 } @max ), '*'); print pack $template => @$_ for @data; __DATA__ Account,Login Name,Password,Web Site,Comments,Extra Google Docs,george123,F0oB@r,http://www.google.com/docs,The GoodleDocs + site,A Amazon,george123,fo0bA7,http://www.amazon.com,The Amazone Kindle site, +B Apple,george123,mM_B39Aa,https://www. ... shorter,My Apple account,C Longer Account,Login Name,Password,Web Site,Comments,D Account,Longer Login Name,Password,Web Site,Comments,E Account,Login Name,Longer Password,Web Site,Comments,F Account,Login Name,Password,Longer Web Site,Comments,G Account,Login Name,Password,Web Site,Longer Comments,H XAccount,XLogin Name,XPassword,XWeb Site,XComments,I

        Output:

        $ pm_pack_fmt_txt.pl Account Login Name Password Web Site + Comments Extra Google Docs george123 F0oB@r http://www.google.com +/docs The GoodleDocs site A Amazon george123 fo0bA7 http://www.amazon.com + The Amazone Kindle site B Apple george123 mM_B39Aa https://www. ... shor +ter My Apple account C Longer Account Login Name Password Web Site + Comments D Account Longer Login Name Password Web Site + Comments E Account Login Name Longer Password Web Site + Comments F Account Login Name Password Longer Web Site + Comments G Account Login Name Password Web Site + Longer Comments H XAccount XLogin Name XPassword XWeb Site + XComments I

        You could also use this technique to create a FORMAT for printf (as suggested by toolic++ earlier).

        Update: s/@max[0 .. $#max]/@max/

        -- Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://998493]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2014-09-02 02:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (18 votes), past polls