Thread 2 Dateien/Tabellen mergen/vergleichen
(2 answers)
Opened by Chibi at 2012-01-07 23:04
Für sowas gibt's doch Datenbanken :)
In Perl würde ich versuchen, das in eine Datenbank-artige Struktur zu packen, die mir auch später noch andere Operationen erlaubt. Das geht natürlich auch einfacher, aber es ist nicht immer gut, sich darauf zu verlassen, dass z.B. die Struktur der Dateien unveränderlich ist (Reihenfolge der Spalten, etc.). Gruß FIFO 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 use warnings; use strict; use Data::Dump qw(dump); my %db; # Datenbank my $using = 'V1'; # Spalte fuer JOIN # Daten einlesen, hier aus DATA-Segment for my $table ('table1', 'table2') { my $id_col; while (my $line = <DATA>) { last if $line !~ /\S/; # Spaltennamen incl. Reihenfolge sichern, # Spaltennummer der $using-Spalte ermitteln if (! exists $db{'col_names'}{$table}) { my @cols = split ' ', $line; grep { $id_col = $_ if $cols[$_] eq $using } 0..$#cols; die "$table does not contain col '$using'\n" if ! defined $id_col; @{$db{'col_names'}{$table}} = @cols; next; } my @cols = split ' ', $line; my $id = $cols[$id_col]; # Daten in Datenbanktabelle einlesen $db{$table}{$id} = { map { @{$db{'col_names'}{$table}}[$_] => $cols[$_] } 0..$#cols }; } } # Spaltennamen fuer Differenz-Tabellen und Join-Tabelle erzeugen, # Namen, die nur in table2 vorhanden sind, an join-Spaltennamen anhaengen @{$db{'col_names'}{'not_in_table1'}} = @{$db{'col_names'}{'table2'}}; @{$db{'col_names'}{'not_in_table2'}} = @{$db{'col_names'}{'table1'}}; @{$db{'col_names'}{'table_join'}} = @{$db{'col_names'}{'table1'}}; for my $col (@{$db{'col_names'}{'table2'}}) { if (! grep { $_ eq $col } @{$db{'col_names'}{'table_join'}}) { push @{$db{'col_names'}{'table_join'}}, $col; } } # Daten mergen, Datensaetze aus table2 ueberschreiben die aus table1 for my $id (keys %{$db{'table2'}}) { if (exists $db{'table1'}{$id}) { %{$db{'table_join'}{$id}} = %{$db{'table2'}{$id}}; } else { %{$db{'not_in_table1'}{$id}} = %{$db{'table2'}{$id}}; } } for my $id (keys %{$db{'table1'}}) { if (! exists $db{'table2'}{$id}) { %{$db{'not_in_table2'}{$id}} = %{$db{'table1'}{$id}}; %{$db{'table_join'}{$id}} = %{$db{'table1'}{$id}}; } } # Entkommentieren, um Datenstruktur anzusehen: # dump(%db); # Ausgabe no warnings 'uninitialized'; for my $table ('table_join', 'not_in_table1', 'not_in_table2') { printf( "$table: %d Zeilen\n\n%s\n", scalar(keys %{$db{$table}}), join("\t", @{$db{'col_names'}{$table}}) ); for my $row (sort keys %{$db{$table}}) { printf( "%s\n", join("\t", map { $db{$table}{$row}{$_} } @{$db{'col_names'}{$table}} ) ); } print "\n"; } __DATA__ V1 V2 V3 V4 V5 ID1 aa nn zz ii ID2 ss rr oo ll ID4 qq mm öö pp ID5 nn vv bb xx V1 V2 V3 V4 V5 V6 ID1 aa nn zz ii 45 ID3 ff xx yy tt 45 ID4 qq mm öö pp 45 ID6 uu kk nn ff 45 ID7 qq ww ee rr 45 Ausgabe: Code: (dl
)
1 table_join: 4 Zeilen Editiert von FIFO: Rohdaten korrigiert, Typo Last edited: 2012-01-09 12:57:36 +0100 (CET) Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it? -- Brian Kernighan: "The Elements of Programming Style"
|