#!/usr/bin/perl # # Format the csv file generated by a skyserver query. # You might want to set skyserver_output_filter to point to this file # # The keys are used as patterns to specify special formats. If the # column headings are longer than the precision specified here, the # format widths will be suitable adjusted. # # If more than one pattern matches, use the longest # %formats = ('Dec' => '%10.7f', 'objId' => '%20s', 'ID\$' => '%20s', '^(l|b)\$' => '%8.4f', 'Mag' => '%.3f', '^RA\$' => '%9.5f', 'MJD' => '%8.2f', '^N\$' => '%5d', '^run\$' => '%4d', '(rowc|colc)' => '%7.2f', ); # # Parse arguments # while($ARGV[0] =~ /^-/) { if($ARGV[0] eq "-h" || $ARGV[0] eq "-?") { warn "\ Usage: format-csv [options] Format a csv file nicely, with constant field widths. Field names that match some patterns are recognised and formatted specially: "; foreach (sort(keys %formats)) { printf STDERR "\t%-10s%6s\n", $_, $formats{$_}; } warn "See also -f and -n options. Options: -h, -? Print this message -f 'name=>fmt' Format fields matching name with format fmt; e.g. \"-f 'Mag=>%.4f'\". You may specify -f more than once. -n Turn off all predefined formats "; exit(0); } elsif($ARGV[0] eq "-f") { shift(@ARGV); $arg = $ARGV[0]; if(!$arg) { warn "-f expects an argument\n"; } elsif($arg !~ /([^=]+)=>(%.*)/) { warn "-f expects an argument of the form \"name=>%format\"; saw " . $arg . "\n"; } else { $formats{$1} = $2; } } elsif($ARGV[0] eq "-n") { undef(%formats); } shift(@ARGV); } # # Read header line and find minimum column widths # chomp($header = <>); @fields = split("(,)", $header);# keep , and empty fields if(@fields[@fields - 1] eq ",") { push(@fields, ''); } # # Are we processing an error message? # if($header !~ /^(#\s)?[a-z0-9_\'|:,]+$/i) { print $header . "\n"; $exit_code = 1; if(!$header) { # could be a single non-named field chomp($next = <>); if($next =~ /^[^ ,]+$/) { # probably a " " " " " " " $exit_code = 0; } print $next . "\n"; } while(<>) { print; } exit $exit_code; } $ofmt = ""; # output format foreach $field (@fields) { if($field eq ",") { next; } $fmt = '%s'; $lenmax = 0; # length of longest match foreach $k (keys %formats) { if($field =~ /$k/i) { if(length($k) > $lenmax) { $lenmax = length($k); $fmt = $formats{$k}; } } } $len = length($field); if($len < 3) { # that\'s silly $len = 3; } if($fmt =~ s/%-?([0-9]+)//) { my($flen) = $1; if($flen > $len) { $len = $flen; } } $fmt =~ s/%//; $fmt = "%${len}$fmt"; if($ofmt) { $ofmt .= " "; print " "; } printf "%${len}s", $field; $ofmt .= $fmt; } $ofmt .= "\n"; print "\n"; # # Process the rest of the file # while(<>) { #print; next; chomp; if($_ =~ /^\s*$/) { next; } if(/\"/) { $line = ""; $n = 0; # which segment foreach (split("\"")) { # protect all real , if($line && $_ eq "") { # \"\", i.e. a quoted \", $n--; $_ = '"'; } else { if($n++%2 == 0) { $_ =~ s/,/\002/g; } else { s/,/\001/g; $_ =~ s/,/\002/g; $_ =~ s/\001/,/g; } } $line .= $_; } printf $ofmt, split("\002", $line); } else { printf $ofmt, split(","); } }