ascii_table_csv.pl 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 15 March 2013
  5. # https://github.com/trizen
  6. # Print a CSV file to standard output as an ASCII table.
  7. use 5.010;
  8. use strict;
  9. use autodie;
  10. use warnings;
  11. use open IO => ':utf8';
  12. use Text::CSV qw();
  13. use Text::ASCIITable qw();
  14. use Getopt::Std qw(getopts);
  15. binmode(STDOUT, ':utf8');
  16. my %opt = (
  17. s => 0,
  18. d => ',',
  19. );
  20. getopts('sw:d:', \%opt);
  21. my $csv_file = shift() // die <<"USAGE";
  22. usage: $0 [options] [csv_file]
  23. options:
  24. -s : allow whitespace in CSV (default: $opt{s})
  25. -d <> : separator character (default: '$opt{d}')
  26. -w <> : maximum width for table (default: no limit)
  27. example: $0 -s -d ';' -w 80 file.csv
  28. USAGE
  29. my %esc = (
  30. a => "\a",
  31. t => "\t",
  32. r => "\r",
  33. n => "\n",
  34. e => "\e",
  35. b => "\b",
  36. f => "\f",
  37. );
  38. $opt{d} =~ s{(?<!\\)(?:\\\\)*\\([@{[keys %esc]}])}{$esc{$1}}g;
  39. ## Parse the CSV file
  40. sub parse_file {
  41. my ($file) = @_;
  42. my %record;
  43. open my $fh, '<', $file;
  44. my $csv = Text::CSV->new(
  45. {
  46. binary => 1,
  47. allow_whitespace => $opt{s},
  48. sep_char => $opt{d},
  49. }
  50. )
  51. or die "Cannot use CSV: " . Text::CSV->error_diag();
  52. my $columns = $csv->getline($fh);
  53. my $lines = 0;
  54. while (my $row = $csv->getline($fh)) {
  55. foreach my $i (0 .. $#{$columns}) {
  56. push @{$record{$columns->[$i]}}, $row->[$i];
  57. }
  58. ++$lines;
  59. }
  60. $csv->eof() or die "CSV ERROR: " . $csv->error_diag(), "\n";
  61. close $fh;
  62. return ($columns, \%record, $lines);
  63. }
  64. ## Create the ASCII table
  65. sub create_ascii_table {
  66. my ($columns, $record, $lines) = @_;
  67. my $table = Text::ASCIITable->new();
  68. $table->setCols(@{$columns});
  69. if ($opt{w}) {
  70. foreach my $column (@{$columns}) {
  71. $table->setColWidth($column, $opt{w} / @{$columns});
  72. }
  73. }
  74. foreach my $i (0 .. $lines - 1) {
  75. $table->addRow(map { $_->[$i] } @{$record}{@{$columns}});
  76. }
  77. return $table;
  78. }
  79. {
  80. local $| = 1;
  81. print create_ascii_table(parse_file($csv_file));
  82. }