in reply to Writing CSV files

As far as I can tell, Text::CSV can handle all of this except writing out with quotes the way I need. It either writes everything with quotes or nothing.
Text::CSV_XS takes a different approach. By default it quotes only fields that need to be quoted for parsability i.e. it quotes fields that have embedded separator or delimiter characters and does not quote fields that do not contain them i.e. foo,7,bar,"x,y",qux. You can also specify always quote to get quote characters delimiting all fields.

You might want to examine your data to make sure that isn't what is happening.

If your fields are not quoted according to their parseability, then it is most likely that they are quoted by field type (as understood by the original app) so that they will be consistent *by field*. In other words if fields 1, 4, and 5 are thought by the original app to contain strings, then fields 1, 4, and 5 will be quoted. Here's a script which will honor the original apps' field definitions - it reads CSV fields (including embedded commas) and writes out the fields quoted as in the original. It uses AnyData, another CSV-capable module. The example uses a DATA section, but the module also supports reading from files.

#!/usr/bin/perl -w use strict; use AnyData; my %is_quoted_field = ( c1=>1, c4=>1, c5=>1 ); my @cols = qw ( c1 c2 c3 c4 c5 c6 ); my $table = adTie('CSV',[<DATA>],'r',{cols=>[@cols]}); while (my $row = each %$table) { my @fields; for (@cols) { my $field = ($is_quoted_field{$_}) ? q{"} . $row->{$_} . q{"} : $row->{$_}; push @fields,$field; } print join(',',@fields)."\n"; } __DATA__ "bye",3,27.6,"green","32",stuff "x,y",5,28.2,"yellow","33",more stuff