#!/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; }