Thread Erste CSV-Zeile als Stringnamen verwenden (7 answers)
Opened by Steven at 2010-10-12 17:43

payx
 2010-10-14 19:01
#141897 #141897
User since
2006-05-04
564 articles
BenutzerIn

user image
Hallo Steven,

so recht klar ist mir nicht, was Dein Problem eigentlich ist.

Von den guten Hinweisen, die Du hier bekommen hast, hast Du eigentlich so gut wie nichts umgesetzt, wenn ich es recht sehe. Beispielsweise der Vorschlag CPAN:Text::CSV zu verwenden, wäre natürlich gut. Eine Lösung wie Deine (und meine hier unten), wird möglicherweise nicht allen Besonderheiten eines csv-Files gerecht (siehe Thread: Quotes, Trennzeichen in Feldern usw.).

Im Kern geht es wohl darum, die Einzelwerte in den Zeilen im csv mit ihren jeweiligen Überschriften zu assoziieren. Das geht am besten mit einem Hash (key = Überschrift, value = Wert). In meinem Beispiel wird das Hash pro Zeile neu erzeugt und gleich wieder ausgedruckt. (Wenn die Daten nicht nur zeilenweise verarbeitet werden sollen, brauchst Du ein Array von HashRefs; vgl. mein erstes Posting.) Ich gehe dabei davon aus, dass die einzelnen Überschriften in Input und Output identisch sind, nur eben unterschiedlich angeordnet; wenn im Input eine Überschrift fehlt, wird ein Defaultwert gesetzt; zusätzliche Überschriften im Input werden ignoriert.

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/perl

use strict;
use warnings;

# config
my $inPath = "internet.csv";
my $outPath = "internet_artikelstamm.csv";
my $outHeader = 'status;artnr;name;short_description';
my %defaultVal = ('status' => 'Aktiviert');
# / config

open (my $inFH, "<", $inPath) || die $!;
open (my $outFH, ">", $outPath) || die $!;

print $outFH "$outHeader\n";

chomp (my $firstRow = <$inFH>);
my @inHeader = split /;/, $firstRow;

while (<$inFH>) {
    chomp($_);
    my @inRow = split /;/, $_; 
    
    my %outRow;
    $outRow{$_}= ($defaultVal{$_} // '') for (split /;/, $outHeader);
    
    for my $col (0..@inHeader-1) {
        $outRow{$inHeader[$col]} = $inRow[$col] if defined ($outRow{$inHeader[$col]});
    }
    next if $outRow{'name'} =~ /\*\*/;
    
    my @printRow;
    push @printRow, $outRow{$_} for split /;/, $outHeader;
    print $outFH (join ";", @printRow) . "\n";
}

close $inFH or die $!;
close $outFH or die $!;

HTH
Grüße
payx

//Edit: Scalar value @inRow[$col] better written as $inRow[$col] line 29.
Last edited: 2010-10-14 19:09:15 +0200 (CEST)

View full thread Erste CSV-Zeile als Stringnamen verwenden