2013-10-02 4 views
2

J'ai un script perl qui fonctionne très bien à l'écran mais lorsque j'essaye de rediriger la sortie vers un fichier csv, j'obtiens l'erreur suivante: Expected fields to an array ref. J'utilise Text::CSV_XS et la ligne qui donne l'erreur est $csv->print ($fh, $_) for @rows;Sortie vers un fichier csv en utilisant Text :: CSV_XS

#!/user/local/bin/perl 
use Text::CSV_XS; 
$|=1; 

sub main { 
    print "Enter file to process: "; 
    my $file = <STDIN>; 
    chomp $file; 

    my @rows; 
    my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1 }); 
    open(INPUT, $file) or die("Input file $file not found.\n"); 
    while(my $line = <INPUT>) { 
     if($line =~ /Assay/) { 
      @words = split(" ",$line); 
      push @rows, $words[1]; 
     } 
     if($line =~/Date/) { 
      @words = split(" ",$line); 
      push @rows, $words[1]; 
      push @rows, $words[2]; 
     } 
     if($line =~/Patient/) { 
      @words = split(" ",$line); 
      push @rows, $words[0]; 
      push @rows, $words[1]; 
      push @rows, $words[2]; 
     } 
     if($line =~/channel_index/) { 
      print $line; 
     } 

     if($line =~/Channel/) { 
      @words = split(" ",$line); 
      push @rows, $words[1]; 
      push @rows, $words[2]; 
     } 
     if($line =~/DCMean/) { 
      @words = split(" ",$line); 
      push @rows, $words[0]; 
      push @rows, $words[1]; 
     } 
    } 

    $csv->eol ("\r\n"); 
    open $fh, ">:encoding(utf8)", "new.csv" or die "new.csv: $!"; 
    $csv->print ($fh, $_) for @rows; 
    close $fh or die "new.csv: $!"; 
    close(INPUT); 
} 

main(); 

Répondre

4

La façon dont vous poussez les valeurs sur @rows, vous obtiendrez juste un énorme tableau plat de scalaires. Ce n'est probablement pas ce que vous voulez.

Considérez ce qui suit:

my @rows; 
push @rows, 'a'; 
push @rows, 'b'; 
push @rows, 'c'; 
push @rows, 'd'; 
push @rows, 'e'; 
push @rows, 'f'; 

nous donne un tableau plat: [a,b,c,d,e,f].

Si ceci:

my @rows; 
push @rows, ['a', 'b', 'c']; 
push @rows, ['d', 'e', 'f']; 

nous donne un tableau imbriqué: [[a,b,c], [d,e,f]].

Il arrive aussi que les tableaux et arrayrefs soient similaires, mais différents. Voir perlreftut. C'est un concept subtil, mais crucial pour le développement avancé de Perl. S'il vous plaît lire et comprendre!

Votre code push pourrait ressembler à ceci:

push @rows, [$words[1], $words[2]]; 

Le [] autour de ces scalaires crée une référence de tableau anonyme. Puisque @rows sera maintenant rempli avec des références de tableau, vous ne devriez pas avoir besoin de changer quoi que ce soit d'autre.

+1

Cela a fonctionné parfaitement. Merci! – Craig

1

Essayez de changer la ligne de rapport d'erreur à suivre:

$csv->print ($fh, \@rows); 

Une citation de Text::CSV_XS documentation CPAN de print fonction

Il attend un tableau ref en entrée (pas un tableau!)

+0

J'ai essayé de faire cela avec le même résultat. – Craig

Questions connexes