2010-01-25 4 views
2

J'ai des données et j'aime faire une simple opération while avec un script Perl. Voici une petite extraction de l'ensemble de données:Comment calculer correctement les longueurs de champs dans un fichier CSV en utilisant Perl?

"numéro", "code", "pays", "gamma", "X1", "X2", "X3", "X4", "X5 " "X6" 1, "DZA", "Algérie", "0,01", 7.44,47.3,0.46,0,0,0.13 2, "AGO", "Angola", "0.00", 6.79," NULL » 0.21,1,0,0.28 3, "BEN", "Bénin", "- 0,01", 7.02,38.9,0.27,1,0,0.05 4, "BWA", "Botswana", "0,06" , 6.28,45.7,0.42,1,0,0.07 5, "HVO", "Burkina Faso", "0.00", 6.15,36.3,0.08,0,0,0.05 6, "BDI", "Burundi", "0.00", 6.38,41.8,0.18,1,0,0

Le certificat t devrait compter la longueur de chaque champ séparé , et stocker les valeurs les plus élevées dans un tableau.

Cependant, la sauvegarde ne fonctionne pas correctement. Voici une partie du code:

@maxl = map length, @terms; 

while(`<INFILE>`) { 
$_ =~ s/[\"\n]//g ; 
@terms = split/$sep/, $_; 
@lengths = map length, @terms; 
for($k = 0, $k <= $#terms, $k++) { 
    if($lengths[$k] > $maxl[$k]) { 
    $maxl[$k] = $lenghts[$k]; 
    } 
} 
print "@lengths\n"; 
} 

Maintenant, le @maxl utilise une partie antérieure du code où il utilise la deuxième ligne de l'ensemble de données. Lorsque j'utilise une commande print juste pour voir les valeurs de l'opération @maxl je reçois:

Dans la boucle while j'ai utilisé une autre déclaration print juste pour voir les autres valeurs, je reçois:

1 3 6 4 4 4 4 1 1 4 
1 3 5 5 4 4 4 1 1 4 
1 3 8 4 4 4 4 1 1 4 
1 3 12 4 4 4 4 1 1 4 
1 3 7 4 4 4 4 1 1 1 
1 3 8 4 4 4 4 1 1 4 
1 3 10 4 4 4 4 1 1 4 
1 3 16 5 4 4 4 1 1 4 
2 3 4 5 3 4 4 1 1 4 
2 3 7 4 4 4 4 1 1 4 
2 3 5 4 4 4 4 1 1 4 
2 3 5 4 4 4 4 1 1 4 
2 3 8 4 4 4 4 1 1 4 
2 3 5 4 4 4 1 1 1 4 

La quatrième colonne, par exemple a évidemment des valeurs supérieures à 3. Le while La boucle était censée sauvegarder les plus grandes valeurs et les remplacer par @maxl.

Qu'est-ce qui n'a pas fonctionné?


... dans la boucle for la virgule sont mal

for($k = 0, $k <= $#terms, $k++) 

Cependant, après le nettoyage que là-bas semble encore être un problème ...

Répondre

9

il y a une faute de frappe ici $maxl[$k] = $lenghts[$k]; pour les débutants (que "utiliser strict" aurait attrapé)

envisager d'utiliser Text::CSV pour l'analyse plus fiable des données séparées par des virgules (il peut aussi gérer d'autres séparateurs):

#!/usr/bin/perl 
use strict; 
use warnings; 
use Text::CSV; 

my $csv = Text::CSV->new(); 
my @max_lengths; 

while (my $line = <INFILE>) { 

    die "Unable to parse '$line'" unless $csv->parse($line); 

    my @column_lengths = map { length } $csv->fields(); 

    for my $i (0 .. $#column_lengths) { 
     if ($column_lengths[$i] > ($max_lengths[$i] || 0)) { 
      $max_lengths[$i] = $column_lengths[$i]; 
     } 
    } 
} 

print "MAX LENGTHS OF EACH FIELD: @max_lengths\n"; 
+0

a oublié de retirer le de mon exemple - doit être remplacé par le comme avant ... – plusplus

+0

remplacé. BTW, vous pouvez modifier vos propres messages –

Questions connexes