Schrift
[thread]7008[/thread]

Probleme mit MLDBM

Leser: 1


<< >> 5 Einträge, 1 Seite
adler1860
 2005-05-23 14:00
#55092 #55092
User since
2005-05-23
2 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hi,

ich möchte eine MLDBM eine Berkley-DB aufbauen, deren value widerum ein Hash ist. D.h. ich habe eine Textdatei mit folgendem inhalt (Suchbegriff, Anzahl)
reisen 302
google 393
ebay 3909
sport 9383
routenplaner 10
flirten 3921
usw.


Mit folgendem Code wird nun die Berkley-DB erzeugt und das funktioniert auch soweit.

Code: (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
#!c:\perl\bin\perl.exe

use MLDBM qw(DB_File Storable);
use Data::Dumper;

my $dbfile = "test.db";
my $txtfile = "kw2005-02.txt";
my $zeile;
my $zeitraum;
my $suchbegriff;
my $anzahl;
my @spalten;
my %hash;
my %uniq;

tie %hash, 'MLDBM', $dbfile or die "Can&´t open $dbfile: $!\n";

open(INPUT, "< $txtfile") or die "Kann $txtfile nicht öffnen $!\n";
while(<INPUT>){
chomp;
$zeile = $_;
($suchbegriff,$anzahl) = split("\t",$zeile);

$zeitraum = $txtfile;
$zeitraum =~ s/kw//;
$zeitraum =~ s/.txt//;

$uniq{ $zeitraum } = $anzahl;
$hash{ $suchbegriff } = \%uniq;

}

print Dumper(\%hash);

untie %hash;


Mein Problem ist nun, dass ich immer nur eine TXT-Datei einlesen kann und die Daten wieder überschrieben werden. Ich möchte aber, dass das Skript die erste TXT-Datei einliest, dann die zweite,... und die Werte aufsummiert werden.

Probiert hab ich das so, funktioniert aber leider nicht.
Code: (dl )
1
2
3
$href = exists $uniq{ $begriff } ? $uniq{ $begriff } : [];
push(@$href,$anzahl);
$hash{ $suchbegriff } = $href;


Kann mir jemand weiterhelfen, ich hab leider mit Perl nicht viel Erfahrung.

Vielen Dank im voraus

Johannes
Thorium
 2005-05-23 16:54
#55093 #55093
User since
2003-08-04
232 Artikel
BenutzerIn
[Homepage] [default_avatar]
Wenn ich dich recht verstanden habe willst du sowas!?

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[...]
my @files = ("kw2005-02.txt", "kw2005-03.txt", "kw2005-03.txt")
[...]

foreach my $file (@files) {    # Fuer jede File in @files
    open(INPUT, "< $file") or die "Kann $file nicht öffnen $!
";
    while(defined my $zeile = <INPUT>) {
         chomp $zeile;

        my ($suchbegriff,$anzahl) = split("\t",$zeile);
    
        my $zeitraum = $file;
        $zeitraum =~ s/kw//;
        $zeitraum =~ s/.txt//;
    
        $uniq{ $zeitraum } += $anzahl;   # += Addiert
        $hash{ $suchbegriff } += \%uniq;
    }
    close(INPUT);
}


Du solltest ausserdem unbedingt
Code (perl): (dl )
1
2
use strict;
use warnings;


benutzen... Vielleicht auch noch
Code (perl): (dl )
use diagnostics;


HTH

Edit: Ich denk defined chomp würde Probleme geben\n\n

<!--EDIT|Thorium|1116853077-->
Per|li|nist der; -en, -en <zu ↑...ist>: a) Anhänger, Vertreter der radikalen Perlinisten die Perl als die einzig wahre Sprache ansehen; b) Mitglied einer perlinistischen Community.
adler1860
 2005-05-23 17:56
#55094 #55094
User since
2005-05-23
2 Artikel
BenutzerIn
[Homepage] [default_avatar]
Vielen Dank erstmal, aber leider funktioniert das so nicht.

Ich bekomm ganz komische Werte (z.B. 79014132 bei reisen,...).

Vielleicht hab ich mich auch falsch bzw. unverständlich ausgedrückt. Ich hab mehrere Textdateien, z.B.

kw2005-01.txt
reisen 302
google 393
ebay 3909
sport 9383
routenplaner 10

und

kw2005-02.txt
reisen 202
google 293
ebay 2909
sport 8383
routenplaner 1210

das Skript soll nun eine Berkley-DB nach folgendem Format aufbauen:

reisen => {'2005-01' =>302,'2005-02' => 202}
google => {'2005-01' =>393,'2005-02' => 293}.....

Wie gesagt, bei nur einer Datei funktioniert es einwandfrei, bei mehreren jedoch nicht, weil die Values immer wieder überschrieben werden.

Ich hoffe, Ihr könnt mir helfen. Ich hab noch ziemlich wenig Erfahrung mit Perl und komm ohne Hilfe einfach nicht weiter.

Vielen Dank im voraus.
Johannes
Crian
 2005-05-23 18:42
#55095 #55095
User since
2003-08-04
5873 Artikel
ModeratorIn
[Homepage]
user image
Ich nehme mal an, Deine Textdateienamenn haben immer das Format "kwYYYY-MM.txt" (wobei YYYY für eine Jahreszahl und MM für eine zweistellige Monatszahl steht). Folgender Ansatz:

Code: (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;

use File::Basename qw/basename/;

my @files = @ARGV;

die "Syntax: " . basename($0) . " Datei1 [Datei2] [Datei3] ...\n" unless @files;

my @labels;

for my $file (@files) {
my ($label = basename($file)) =~ s~^kw(.+)\.txt$~$1~;
die "kann keinen Label zur Datei '$file' finden\n" unless defined $label and length $label;
push @labels, $label;
}

die "Anzahl Dateien und Anzahl Label sind unterschiedlich\n" unless @label == @files;

my %db;

for my $i (0 .. $#files) {
my $file = $files[$i];
my $label = $labels[$i];

open(F, $file) or die "Kann '$file' nicht oeffnen: $!\n";
while (<F>) {
chomp;
next if m/^\s*$/;
my ($suchbegriff, $anzahl) = split("\t",$zeile);
$db{$suchbegriff}->{$label} = $anzahl;
# oder: push @{ $db{$suchbegriff}->{$label} }, $anzahl;
}
close F or warn $!;
}

use Data::Dumper; $Data::Dumper::Sortkeys = 1;
print Dumper \%db;


ungetestet und direkt ins Forenfenster getippt, könnte aber zumindestens als Ansatz passen.\n\n

<!--EDIT|Crian|1116859436-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Dubu
 2005-05-23 18:42
#55096 #55096
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Versuch statt
Code: (dl )
1
2
    $uniq{ $zeitraum } = $anzahl;
$hash{ $suchbegriff } = \%uniq;

einfach mal
Code: (dl )
    $hash{$suchbegriff}{$zeitraum} = $anzahl;
<< >> 5 Einträge, 1 Seite



View all threads created 2005-05-23 14:00.