Thread CSV Feldlänge bestimmen
(16 answers)
Opened by sara456 at 2014-05-23 16:54 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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 #!/usr/bin/perl use strict; use warnings; my $format_file = 'format.csv'; my $data_file = 'data.csv'; my $out_file = 'data_out.csv'; # definiere die Möglichen Formate # die einträge sind: # - check : Prüfung des Datensatzes gibt 1 oder 0 zurück # - force : Entfernen aller unerlaubten zeichen, fibt den veränderten String zurück # - format : Formatieren des Datensatzes, gibt den formatieren String zurück my %known_format_types=( 'Alphanumerisch' => { check => sub{ return $_[0] =~ /^[a-z0-9]*$/is?1:0 }, force => sub{ $_[0] =~ s/[^a-z0-9]+//igs; return $_[0] }, format => sub{ my ($data,$length)=@_; return sprintf('%-'.$length.'s',$data); }, }, 'Numerisch' => { check => sub{ return $_[0] =~ /^\d*$/is?1:0 }, force => sub{ my ($data) = @_; $data =~ s/\D+//igs; return $_[0] if($data); return 0; }, format => sub{ my ($data,$length)=@_; return sprintf('%0'.$length.'u',$data); }, }, ); my $format = load_format($format_file); # Ein- und Ausgabe öffnen open(my $fhi, '<:encoding(UTF-8)', $data_file) or die("ERROR OPEN $data_file ($!)\n"); open(my $fho, '>:encoding(UTF-8)', $out_file) or die("ERROR OPEN $out_file ($!)\n"); # alle Daten durch gehen while(my $line = <$fhi>) { # zeilenende entfernen chomp($line); # Zeile zerlegen my @data=split(/;/, $line); my @outd; # Daten duchgehen for my $pos (0 .. $#data) { # Wenn keine Formatangabe vorhanden ist, Spalte überspringen. next unless( $format->[$pos] ); # Informationen zur Formatierung über diese Zeile holen. my $type = $format->[$pos]->{type}; my $length = $format->[$pos]->{length}; my $pos_out= $format->[$pos]->{position}; my $code = $known_format_types{$type}; # Wenn kein Code vorhanden ist, Splate überspringen. unless( $code ) { warn("ERROR Unkannter Typ für Zeile $. Spalte $pos\n"); next(); } my $result = $data[$pos]; # Daten prüfen warn("WARN Fehlerhaftes Format $type für Zeile $. Spalte $pos |[$result]|\n") unless( $code->{check}->($result) ); # Daten säubern $result = $code->{force}->($result); # Daten formatieren $result = $code->{format}->($result,$length); # Daten zurück schreiben $outd[$pos_out] = $result; } # Zeile in Ausgabe schreiben print $fho join(';',@outd).$/; } close($fhi); close($fho); ######################################################################## # FUNKTIONEN ######################################################################## sub load_format { my ($file) = @_; my @data; open(my $fh, '<:encoding(UTF-8)', $file) or die("ERROR OPEN $file ($!)\n"); # ignoriere erste zeile: <$fh>; while(my $line = <$fh>) { # Entferne Zeilenende chomp($line); # zerlege Zeile my @d = split(/\s+/,$line); # prüfe format die("FORMAT ERROR Zeile $. ($file) |[$line]|\n") if(@d < 3); die("FORMAT ERROR Zeile $. spalte 1 ($file) |[$d[0]]|\n") if($d[0]=~/\D/); die("FORMAT ERROR Zeile $. spalte 2 ($file) |[$d[1]]|\n") if($d[1]=~/\D/); die("FORMAT ERROR Zeile $. spalte 3 ($file) |[$d[2]]|\n") if($d[2]=~/\D/); # setze Datensatz ein $data[$d[0]-1] = {position => $d[1]-1, length => $d[2], type => $d[3]}; } close($fh); return \@data; } |