2 Stimmen

Wie kann ich die Längen der Felder in einem CSV-Dokument unter Verwendung von Perl korrekt berechnen?

Ich habe ein Dataset und möchte eine einfache while-Operation mit einem Perl-Skript durchführen. Hier ist ein kleiner Ausschnitt aus dem Datensatz:

"number","code","country","gamma","X1","X2","X3","X4","X5","X6" 1,"DZA","Algerien","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","Benin","-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,1,0,0.05 6,"BDI","Burundi","0.00",6.38,41.8,0.18,1,0,0

Das Skript soll die Länge jedes durch , getrennten Feldes zählen und die höchsten Werte in einem Array speichern.

Allerdings funktioniert das Speichern nicht richtig. Hier ist ein Teil des Codes:

@maxl = map length, @terms;

while(``) {
$_ =~ 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";
}

Jetzt verwendet @maxl einen früheren Teil des Codes, in dem die zweite Zeile des Datensatzes verwendet wird. Wenn ich einen print-Befehl nur verwende, um die Werte der @maxl-Operation zu sehen, erhalte ich:

1 3 7 4 4 4 4 1 1 5

In der while-Schleife benutzte ich einen weiteren print-Befehl, um die anderen Werte zu sehen, erhalte ich:

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

Die vierte Spalte hat offensichtlich Werte, die größer als 3 sind. Die while-Schleife sollte die größten Werte speichern und diese Werte in @maxl substituieren.

Was ist schiefgelaufen?


...in der for-Schleife sind die Kommas falsch

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

Nachdem das behoben wurde, scheint es immer noch ein Problem zu geben...

9voto

plusplus Punkte 1962

Hier gibt es einen Tippfehler $maxl[$k] = $lenghts[$k]; um anzufangen (den 'use strict' hätte abfangen können)

Betrachten Sie die Verwendung von Text::CSV für zuverlässigere Analyse von kommaseparierten Daten (es kann auch andere Trennzeichen verarbeiten):

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

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

while ( my $line =  ) {

    die "Unfähig, '$line' zu analysieren" 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 "MAXIMALE LÄNGEN JEDES FELDES: @max_lengths\n";

0 Stimmen

Vergessen, das aus meinem Beispiel zu entfernen - muss wieder durch das ersetzt werden...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X