Schrift
[thread]6134[/thread]

[PROBLEM] --> vergleich von 2 Dateien mit PERL



<< >> 8 Einträge, 1 Seite
Gast Gast
 2004-03-11 17:03
#80875 #80875
Hallo,

ich habe ein ziemlich kompliziertes Problem zu lösen, wäre für jede Hilfe unendlich dankbar:

Ich habe 2 Textdateien.
Eine ist wie folgt aufgebaut:

Quote
0402100397988BZ ALTREI B. JOHANNES ZWERGER PLATZ 5 39040 DIREZIONE DIDATTICA PER LA SCUOLA LINGUA TEDESCA ORA NON RICON.87932000471882144 001ED0DSCUOLE DI INSEGNAMENTO PUBBLICO S 80024320212 2K040487827000000001*


dieser File enthält ca 6000 solcher Records.
Ich muss diesen File mit einem anderen abgleichen, der ca 600 Records enthält, welcher so aufgebaut ist:
Quote
00099430217

jeder dieser records entspricht einem Record des ersten Files, und zwar immer zwischen Zeichen 395 und 410.

Ich muss nun herausfinden, welche der Records aus File 2 sich in File 1 befinden und diese Zeilen dann herauslöschen.

Mein Ansatz ist so:

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
#!/usr/bin/perl

open(F1, "/home/hallohallo/sales/seatTOT") || die "Can't open the file: seatTOT\n";
while (<F1>) {
chop;
push (@SEAT , $_);
$newSEAT = substr(@SEAT, 394, 16);
}
close (F1);


open(F2, "/home/hallohallo/sales/CLIENTI_BKOM") || die "Can't open the file CLIENTI_BKOM\n";
while (<F2>) {
chop;
$PI{$_} = 1;
}
close (F2);

#$newSEAT = $newSEAT {substr($PI, 394, 16)};

foreach $LL (@SEAT) {
if ($newSEAT{$LL} == 1) {
print $LL . "\n";
}
}




#print $SEAT[2000];

exit;
~


Hier komm ich nun aber nicht mehr recht weiter...
Kann mir bitte jemand helfen?

Danke im Vorraus,
HM
renee
 2004-03-11 17:52
#80876 #80876
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Vorschlag:

Lese die 1.Datei in ein Array... Danach die 2. Datei in einen Hash lesen, wobei die Zahl als Key genommen wird und als Value nimmst Du einfach '1'.
Danach: Für jedes Element des Arrays teste, ob Element im Hash vorhanden ist. Wenn ja, dann lösche das Element aus dem Array...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Ronnie
 2004-03-11 18:24
#80877 #80877
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Renee's Vorschlag als Code:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my %hash = ( 16 => 1, 17 =>1, 145 => 1 );
my @array = qw( 192 16 168 17 145 139 97 43 74);
my @results;

foreach my $id (0 .. $#array) {
 push @results, $array[$id] unless (scalar grep(/$id/, keys %hash));
}

print Dumper(\@results);

@renee: Wieso eigentlich der hash?

EDIT1: Code bereinigt.\n\n

<!--EDIT|Ronnie|1079022526-->
renee
 2004-03-11 18:39
#80878 #80878
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Weil Du dann schneller Abgleichen kannst, ob die Zeile aus der 1. Datei eine Zahl aus der 2.Datei enthält. Du brauchst nicht 2 for(each)-Schleifen.

Wenn man es anders besser machen kann, lasse ich mich gerne belehren...
Der code, so wie ich ihn dachte (ungefähr):
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
# Variablen deklarieren
my @lines_file1 = ();
my %hash = ();
# Pfade zu den Dateien
my $file1 = 'Pfad/zur/Datei1';
my $file2 = 'Pfad/zur/Datei2';
my $out = 'Pfad/zur/Zieldatei';

# einlesen der 1. Datei
open(R_FILEONE,"<$file1") or die $!;
while(my $line = <R_FILEONE>){
 push(@lines_file1,$line);
}
close R_FILEONE;

# einlesen der 2. Datei
open(R_FILETWO,"<$file2") or die $!;
while(my $line = <R_FILETWO>){
 chomp $line;
 $hash{$line} = 1;
}
close R_FILETWO;

# überprüfen, ob die Zeile aus der 1.Datei eine Zahl aus der 2. Datei enthält
foreach(@lines_file1){
 my $check = substr($_,394,16); # Zahl in der langen Zeile raussuchen
 if($hash{$check}){
   $_ = '';
 }
}

# Zieldatei schreiben
open(W_TARGET,">$out") or die $!;
foreach(@lines_file1){
 print W_TARGET $_ if($_);
}
close W_TARGET;
\n\n

<!--EDIT|renee|1079023276-->
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
pq
 2004-03-11 18:56
#80879 #80879
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
[quote=Ronnie,11.03.2004, 17:24]
Code: (dl )
  push @results, $array[$id] unless (scalar grep(/$id/, keys %hash));

@renee: Wieso eigentlich der hash?[/quote]
ist dir mal in den sinn gekommen, dass der hash genau dazu da ist,
dieses überflüssige grep einzusparen?
push @results, $array[$id] unless exists $hash{$id};
nebenbei bemerkt ist ein test auf m/$id/ nicht ausreichend. es muss
am anfang und ende verankert werden, denn z.B. $id=2 passt auch auf 12
oder auf 23 etc.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
Ronnie
 2004-03-11 19:06
#80880 #80880
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
[quote=pq,11.03.2004, 17:56]ist dir mal in den sinn gekommen, dass der hash genau dazu da ist,
dieses überflüssige grep einzusparen?
push @results, $array[$id] unless exists $hash{$id};
nebenbei bemerkt ist ein test auf m/$id/ nicht ausreichend. es muss
am anfang und ende verankert werden, denn z.B. $id=2 passt auch auf 12
oder auf 23 etc.[/quote]
Danke pq,
auf erstes hätte ich kommen können, zweites ist außerordentlich peinlich.
Gruss,
Ronnie
havi
 2004-03-12 08:11
#80881 #80881
User since
2003-08-04
2036 Artikel
BenutzerIn
[Homepage]
user image
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
40
41
42
43
44
#!/usr/bin/perl

use warnings;
use strict;

open(EIN, "<Datei2.txt") or die $!;

my (%pnr1, $cnt);

$cnt = 0;

while(<EIN>) {
chomp;
my @f = split(/\t/);
$pnr1{join('|',@f[1..2])} = 1;
++$cnt % 1000 or print "Bei Satz $cnt.\n"
} # while

print "Fertig mit $cnt Saetzen.\n";

close(EIN) or die $!;

open(EIN, "<Datei2.txt") or die $!;
open(AUS, ">Gefunden.txt") or die $!;

$cnt = 0;

while(<EIN>) {
my $vergleich = su_strip(su_strip(substr($_,67,30))."|".substr($_,157,30));
print AUS $_ if defined $pnr1{$vergleich};
++$cnt % 1000 or print "Bei Satz $cnt.\n"
} # while

print "Fertig mit $cnt Saetzen.\n";

close(EIN) or die $!;
close(AUS) or die $!;

sub su_strip {
my $s = shift;
$s =~ s/\s+$//;
$s =~ s/^\s+//;
$s;
}


Gruss
Crian
 2004-03-12 16:17
#80882 #80882
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
Sieht gut aus. Aber ist der doppelte Aufruf von su_strip

Quote
Code: (dl )
my $vergleich = su_strip(su_strip(substr($_,67,30))."|".substr($_,157,30));


wirklich nötig?

Und willst Du bei beiden "EIN" Dateien wirklich die gleichen Dateien öffnen? Müsste es im zweiten Fall nicht die erste Datei sein, in der man die Einträge aus der vorher eingelesenen zweiten Datei untersucht?\n\n

<!--EDIT|Crian|1079101091-->
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
<< >> 8 Einträge, 1 Seite



View all threads created 2004-03-11 17:03.