I ended up looking at three possible solutions, all in Perl.
All three use Text::CSV as a base, to read in the CSV.
Before I settled on a prepared Table package, I just tried doing it manually. This was straightforward, but a little tedious. I had to manually determine max field lengths and draw the required pieces. Even so, a well-spaced Perl script doing this only took 78 lines.
I then looked at the Perl Text::Table package, at http://search.cpan.org/~shlomif/Text-Table-1.131/lib/Text/Table.pm . From a very quick look, this looked like what I needed. However, what I discovered is that I really didn't understand the documentation, and the examples didn't help. I gave up on this.
I then discovered Text::ASCIITable, at http://search.cpan.org/~lunatic/Text-ASCIITable-0.20/lib/Text/ASCIITable.pm . There were enough examples showing what I needed to do so that it was easy to build the script I needed. The only problem I ran into was that the "draw()" method didn't appear to work (did nothing), although just "print $table" worked fine. The resulting solution was only 31 lines long.
This is the entire script:
#! /bin/perl
use strict;
use Text::CSV;
use Text::ASCIITable;
my $csv = Text::CSV->new();
my $filename = shift @ARGV;
my $fh;
if (defined $filename) {
open $fh, "<$filename";
}
else {
$fh = *STDIN;
}
my $asciitable = Text::ASCIITable->new();
$asciitable->setOptions('reportErrors', 1);
my $firstRow = $csv->getline($fh);
my @firstRowFields = @$firstRow;
my $numColumns = $#firstRowFields + 1;
$asciitable->setCols(@firstRowFields);
while (my $row = $csv->getline($fh)) {
$asciitable->addRow($row);
}
print $asciitable;
exit(0);