/* Converts an output generated with list and listoutput into a CSV /* requires Perl /* Note that depending on how many fields you are listing, ArcInfo has /* two list formats, what I call column and row formats. /* This AML will handle both formats transparently. /* Arguments: noheader -- does not include column headers in output file /* norecord -- does not include record column that Arc automatically adds /* quiet -- suppress completion message /* Written by Christopher Eykamp for the 2.11 Toolbox Project, Qatar (C) 1996-1997 /* Permission granted for free use and reproduction, under terms and conditions /* of the GNU General Public License /* Contact the author: email: chris@eykamp.com internet: http://www.eykamp.com &args listfile args:rest &if [null %listfile%] &then &do &ty Syntax: csv {noheader} {norecord} {quiet} &stop &end &if [token [unquote [locase %args%]] -find 'noheader'] > 0 &then &s noheader 1 &else &s noheader 0 &if [token [unquote [locase %args%]] -find 'norecord'] > 0 &then &s norecord 1 &else &s norecord 0 &if [token [unquote [locase %args%]] -find 'quiet'] > 0 &then &s quiet .TRUE. &else &s quiet .FALSE. /* First determine if perl exists on the system... &dv .perl$exists &s tmpfile [scratchname -prefix xxperl -file] &sys perl -e "open OUT,[quote >%tmpfile%] [unquote ';'] print OUT '&s .perl$exists .TRUE.'" &if [exists %tmpfile% -file] &then &r %tmpfile% &s x [delete %tmpfile% -file] &if not [variable .perl$exists] &then &do &ty &ty Sorry -- I cannot find Perl, and I need it to run this program. &ty If you have Perl installed, make sure that it is on your system's search path. &ty If you are experiencing system difficulties, please see your system administrator. &ty For more information about how to get Perl, see http://www.eykamp.com/arcinfo/perlresources.htm &stop &end &else &dv .perl$exists /* Now run the list conversion program &s listfile2 %listfile%.csv &sys perl -x %AML$FULLFILE% %listfile% %listfile2% %noheader% %norecord% &if not %quiet% &then &ty Converted %listfile% into a CSV called %listfile%.csv &return /*************** # This all gets very messy because we are dealing with space-delineated files that have fields that # themselves contain spaces... with no quotes or anything. Messy, messy, messy. And what if a field # a comma??? We quote it here... #!perl ($in,$out,$nohead,$norec)=@ARGV; open(IN,"<$in") || die "Could not open input file $in: $!\n"; open(OUT,">$out") || die "Could not open output file $out: $!\n"; # First line will be a header line if we have a column-format listing, # or a bare number if we are in row format my $line = ; my $linex = $line; # Make a working copy we can trash $linex =~ s/\s//g; # Strip out any whitespace if ($linex =~ /^\d+$/) { $mode = "row" } # Only a number -- we have row format data else { $mode = "col" } # Something else -- must be a header row for col format #print "Detected $mode mode file\n"; if ($mode eq "col") { printline($line) if !$nohead; @cols=split(/\s+/,$line); @lines=; @positions=(); # Array of positions as if all items were string $pos=0; # Now calulate the column positions... while ($_ = shift @cols) { $pos=index($line,$cols[0],$pos)+1; # includes trailing space push(@positions,$pos); } pop @positions; # Adjust the column positions if need-be by examining spacing details foreach $line (@lines) { chomp($line); my @adjpos = (); foreach $pos (@positions) { while (substr($line,$pos,1) ne ' ' && substr($line,$pos,1) ne '' && $pos >= 0) { $pos -- } push(@adjpos,$pos); } @positions = @adjpos; } # Tack on a final entry of 999 push(@positions,999); # Print data $first = 0; foreach $line (@lines) { @positionsx = @positions; my $pos = 0; while(@positionsx) { my $len=$positionsx[0]-$pos; my $data=substr($line,$pos,$len); $pos=shift(@positionsx); push(@data,$data); } printline3(@data); undef @data; } } else { # Row format! my $ctr = 0; chomp($line); $line =~ s/^\s*//; # Strip off any leading whitespace my $cols = "Record"; $data{"Record"} = $line; my $first = 1; while($line = ) { $ctr++; chomp($line); $line =~ s/^\s*//; # Strip off any leading whitespace if ($line =~ /^\d+$/) { # Check if line is a lone number printline($cols) if $first and !$nohead; printline2($cols,\%data); undef %data; # Just a precaution... $cols="Record"; $line =~ s/\s//g; # Strip line of whitespace $data{"Record"} = $line; $first = 0; next; } @_=split(/\s*=\s*/,$line,2); # Split on the "=", with a maximum of 2 fields $cols.=" $_[0]"; $data{$_[0]} = $_[1]; } printline2($cols,\%data); } ################### # 3 different print routines for 3 different occasions... sub printline { my $line = $_[0]; $line =~ s/^\s*//; # Strip off any leading whitespace chomp($line); @fields = split(/\s+/,$line); shift(@fields) if $norec; $first = shift(@fields); print OUT quote($first); foreach $field (@fields) { print OUT ",".quote($field) } print OUT "\n"; } sub printline2 { my $cols = $_[0]; my %line = %{$_[1]}; @fields = split(/\s+/,$cols); shift(@fields) if $norec; $first = shift(@fields); print OUT quote($line{$first}); foreach $field (@fields) { print OUT ",".quote($line{$field}) } print OUT "\n"; } sub printline3 { @fields=@_; shift(@fields) if $norec; $first = shift(@fields); $first=~s/^\s*//; $first=~s/\s*$//; chomp($first); print OUT quote($first); foreach $field (@fields) { chomp($field); $field=~s/^\s*//; $field=~s/\s*$//; print OUT ",".quote($field); } print OUT "\n"; } # Add quotes to values with commas in them... sub quote { if ($_[0]=~/,/) { return "\"$_[0]\"" } else { return $_[0] } }