Schrift
[thread]11930[/thread]

Doppelte Zeilen in Dateien löschen

Leser: 2


<< >> 3 Einträge, 1 Seite
Gast Gast
 2008-05-29 02:22
#110424 #110424
Hallo,
ich habe mehrere Dateien.
1-tmp.lst, 2-tmp.lst, 3-tmp.lst, ..., 20-tmp.lst

diese enthalten alle daten die teilweise doppelt vorhanden sind. es sollen aus den ganzen kleinen dateien eine große gemacht werden und dann die doppelten einträge verschwinden.

ich denke mal alle zeilen als key in nen hash zu packen kann nicht die Lösung sein,
vorallen desswegen nicht weil doch einige mb zusammen kommen...

wie kann ich das relativ speicher-sparend und effektiv realisieren?
murphy
 2008-05-29 05:22
#110425 #110425
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Ohne irgendeine Art von assoziativem Array lässt sich dieses Problem nicht lösen. Bei einer Gesamtdatengröße von einigen Megabyte ist die Verwendung eines gewöhnlichen Perlhashes auch sicher kein Problem. Problematisch wird es erst, wenn die Datenmenge die Größe des Arbeitsspeichers erreicht. In dem Fall sollte man dann vermutlich auf eine Datenbank zurückgreifen (CPAN:DBD::DBM reicht dafür schon völlig).
When C++ is your hammer, every problem looks like your thumb.
topeg
 2008-05-29 08:18
#110426 #110426
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Mach doch eine MD5-Summe über die Zeile. Je nachdem wie lang die Zeilen sind sparst du Speicherplatz.
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
#!/usr/bin/perl

use strict;
use warnings;
use Digest::MD5 'md5_hex';

my $basepath='./data/';
my @files=map{"$_-tmp.lst"}(1..3);

print "@files\n";

my %lines;
for my $file (@files)
{
 open(my $data,'<',$basepath.$file) or die "Konnte $file nicht oeffnen ($!)\n";
 my $cnt=0;
 while(my $line=<$data>)
 {
  $cnt++;
  my $md5=md5_hex($line);
  my $pos={file=>$file, line=>$cnt};
  if(exists($lines{$md5}))
  { push(@{$lines{$md5}},$pos) }
  else
  { $lines{$md5}=[$pos]; }
 }
 close($data);
}

my @doubles;
while(my($key,$data)=each(%lines))
{
 if(@$data>1)
 { push(@doubles,$data) }
}
undef(%lines);

@doubles=sort{$a->[0]->{file} cmp $b->[0]->{file} or $a->[0]->{line} <=> $b->[0]->{line}}@doubles;

print "gefundene Doppelte:\n";
print '-'x10,"\n";
for my $double (@doubles)
{
 for my $line (@$double)
 { print '  '.$line->{file}.' -> '.$line->{line}."\n"; }
 print '-'x10,"\n";
}
<< >> 3 Einträge, 1 Seite



View all threads created 2008-05-29 02:22.